home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 51 / Amiga Format CD51 (2000-03-10)(Future Publishing)(GB)[!][issue 2000-04].iso / -in_the_mag- / workbench / term_4.8 / extras / source / term-source.lha / Config.c < prev    next >
C/C++ Source or Header  |  1997-10-13  |  69KB  |  3,121 lines

  1. /*
  2. **    Config.c
  3. **
  4. **    Configuration processing routines
  5. **
  6. **    Copyright © 1990-1997 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* Reset routine function pointer. */
  17.  
  18. typedef VOID (* RESET)(APTR,STRPTR);
  19.  
  20. /*****************************************************************************/
  21.  
  22.     /* Local routines. */
  23.  
  24. STATIC BOOL ReadSystemPrefs(STRPTR Name, ULONG ID, APTR Data, LONG Size, LONG Count);
  25. STATIC VOID ResetSerialConfig(struct SerialSettings *SerialConfig);
  26. STATIC VOID ResetModem(struct ModemSettings *ModemConfig);
  27. STATIC VOID ResetScreen(struct ScreenSettings *ScreenConfig);
  28. STATIC VOID ResetTerminal(struct TerminalSettings *TerminalConfig);
  29. STATIC VOID ResetEmulation(struct EmulationSettings *EmulationConfig);
  30. STATIC VOID ResetClip(struct ClipSettings *ClipConfig);
  31. STATIC VOID ResetCapture(struct CaptureSettings *CaptureConfig);
  32. STATIC VOID ResetTranslationFile(STRPTR Here, STRPTR PathBuffer);
  33. STATIC VOID ResetMacroFile(STRPTR Here, STRPTR PathBuffer);
  34. STATIC VOID ResetCursorFile(STRPTR Here, STRPTR PathBuffer);
  35. STATIC VOID ResetFastMacroFile(STRPTR Here, STRPTR PathBuffer);
  36. STATIC VOID ResetSpeechFile(STRPTR Here, STRPTR PathBuffer);
  37. STATIC VOID ResetSoundFile(STRPTR Here, STRPTR PathBuffer);
  38. STATIC VOID ResetAreaCodeFile(STRPTR Here, STRPTR PathBuffer);
  39. STATIC VOID ResetPhonebookFile(STRPTR Here, STRPTR PathBuffer);
  40. STATIC VOID ResetHotkeyFile(STRPTR Here, STRPTR PathBuffer);
  41. STATIC VOID ResetTrapFile(STRPTR Here, STRPTR PathBuffer);
  42. STATIC VOID ResetFile(struct FileSettings *FileConfig, STRPTR PathBuffer);
  43. STATIC VOID ResetPath(struct PathSettings *PathConfig, STRPTR PathBuffer);
  44. STATIC VOID ResetMisc(struct MiscSettings *MiscConfig);
  45. STATIC VOID ResetCommand(struct CommandSettings *UnusedCommandConfig);
  46. STATIC VOID ResetTransfer(struct TransferSettings *TransferConfig, STRPTR DefaultLib);
  47. STATIC VOID ResetNewConfigEntry(APTR To, LONG Type);
  48. STATIC BOOL WriteConfigChunk(struct IFFHandle *Handle, struct Configuration *LocalConfig, LONG Type, APTR TempBuffer, STRPTR Password);
  49. STATIC LONG IsConfigChunk(ULONG ID);
  50. STATIC BOOL WriteConfigChunks(struct IFFHandle *Handle, struct Configuration *LocalConfig, APTR TempBuffer, STRPTR Password);
  51. STATIC BOOL ClosePhonebookFile(struct IFFHandle *Handle);
  52. STATIC struct IFFHandle *CreatePhonebookFile(STRPTR Name, PhonebookHandle *PhoneHandle);
  53. STATIC BOOL DumpPhonebookRates(struct IFFHandle *Handle, struct PhoneEntry *Entry);
  54. STATIC BOOL DumpPhonebookGroups(struct IFFHandle *Handle, struct List *GroupList);
  55. STATIC BOOL DumpPhonebookFile(struct IFFHandle *Handle, APTR TempBuffer, PhonebookHandle *PhoneHandle);
  56. STATIC BOOL ReadConfigChunk(struct IFFHandle *Handle, struct Configuration *LocalConfig, LONG Type, LONG Len, STRPTR Password);
  57.  
  58. /*****************************************************************************/
  59.  
  60. STATIC BOOL                    FontPrefsRead        = FALSE,
  61.                             FontPrefsReadFailed    = FALSE;
  62. STATIC struct FontPrefs        FontPrefs[3];
  63.  
  64. /*****************************************************************************/
  65.  
  66. STATIC UWORD SizeTable[] =
  67. {
  68.     sizeof(struct SerialSettings),
  69.     sizeof(struct ModemSettings),
  70.     sizeof(struct CommandSettings),
  71.     sizeof(struct ScreenSettings),
  72.     sizeof(struct TerminalSettings),
  73.     sizeof(struct PathSettings),
  74.     sizeof(struct MiscSettings),
  75.     sizeof(struct ClipSettings),
  76.     sizeof(struct CaptureSettings),
  77.     sizeof(struct FileSettings),
  78.     sizeof(struct EmulationSettings),
  79.     sizeof(struct TransferSettings),
  80.     MAX_FILENAME_LENGTH,                /* Translation file name */
  81.     MAX_FILENAME_LENGTH,                /* Macro file name */
  82.     MAX_FILENAME_LENGTH,                /* Cursor file name */
  83.     MAX_FILENAME_LENGTH,                /* Fast macro file name */
  84.     MAX_FILENAME_LENGTH,                /* Speech file name */
  85.     MAX_FILENAME_LENGTH,                /* Sound file name */
  86.     MAX_FILENAME_LENGTH,                /* Area code file name */
  87.     MAX_FILENAME_LENGTH,                /* Phonebook file name */
  88.     MAX_FILENAME_LENGTH,                /* Hotkey file name */
  89.     MAX_FILENAME_LENGTH                    /* Trap file name */
  90. };
  91.  
  92. STATIC RESET ResetTable[] =
  93. {
  94.     (RESET)ResetSerialConfig,
  95.     (RESET)ResetModem,
  96.     (RESET)ResetCommand,
  97.     (RESET)ResetScreen,
  98.     (RESET)ResetTerminal,
  99.     (RESET)ResetPath,
  100.     (RESET)ResetMisc,
  101.     (RESET)ResetClip,
  102.     (RESET)ResetCapture,
  103.     (RESET)ResetFile,
  104.     (RESET)ResetEmulation,
  105.     (RESET)ResetTransfer,
  106.     (RESET)ResetTranslationFile,
  107.     (RESET)ResetMacroFile,
  108.     (RESET)ResetCursorFile,
  109.     (RESET)ResetFastMacroFile,
  110.     (RESET)ResetSpeechFile,
  111.     (RESET)ResetSoundFile,
  112.     (RESET)ResetAreaCodeFile,
  113.     (RESET)ResetPhonebookFile,
  114.     (RESET)ResetHotkeyFile,
  115.     (RESET)ResetTrapFile
  116. };
  117.  
  118. STATIC ULONG TypeTable[] =
  119. {
  120.     ID_SERL,
  121.     ID_MODM,
  122.     ID_COMD,
  123.     ID_SCRN,
  124.     ID_TRML,
  125.     ID_PATH,
  126.     ID_MISC,
  127.     ID_CLIP,
  128.     ID_CPTR,
  129.     ID_FILE,
  130.     ID_EMLN,
  131.     ID_XFER,
  132.     ID_XLNM,
  133.     ID_MFNM,
  134.     ID_CRNM,
  135.     ID_FMNM,
  136.     ID_SPNM,
  137.     ID_SONM,
  138.     ID_ACNM,
  139.     ID_PBNM,
  140.     ID_HKNM,
  141.     ID_TRNM
  142. };
  143.  
  144. #define NUM_STOPS (sizeof(Stops) / (2 * sizeof(ULONG)))
  145.  
  146. STATIC LONG Stops[] =
  147. {
  148.     ID_TERM,ID_CAT,
  149.     ID_TERM,ID_VERS,
  150.     ID_TERM,ID_DIAL,
  151.     ID_TERM,ID_DAT2,
  152.     ID_TERM,ID_DATE,
  153.     ID_TERM,ID_PHON,
  154.     ID_TERM,ID_PSWD,
  155.  
  156.     ID_TERM,ID_SERL,
  157.     ID_TERM,ID_MODM,
  158.     ID_TERM,ID_COMD,
  159.     ID_TERM,ID_SCRN,
  160.     ID_TERM,ID_TRML,
  161.     ID_TERM,ID_PATH,
  162.     ID_TERM,ID_MISC,
  163.     ID_TERM,ID_CLIP,
  164.     ID_TERM,ID_CPTR,
  165.     ID_TERM,ID_FILE,
  166.     ID_TERM,ID_EMLN,
  167.     ID_TERM,ID_XFER,
  168.     ID_TERM,ID_WINF,
  169.     ID_TERM,ID_GRUP,
  170.     ID_TERM,ID_XLNM,
  171.     ID_TERM,ID_MFNM,
  172.     ID_TERM,ID_CRNM,
  173.     ID_TERM,ID_FMNM,
  174.     ID_TERM,ID_SPNM,
  175.     ID_TERM,ID_SONM,
  176.     ID_TERM,ID_ACNM,
  177.     ID_TERM,ID_PBNM,
  178.     ID_TERM,ID_HKNM,
  179.     ID_TERM,ID_TRNM
  180. };
  181.  
  182. /*****************************************************************************/
  183.  
  184. enum    {    CR_IGNORE,CR_ASCR,CR_ASCRLF };
  185. enum    {    LF_IGNORE,LF_ASLF,LF_ASLFCR };
  186.  
  187. /*****************************************************************************/
  188.  
  189. VOID
  190. StripGlobals(struct Configuration *LocalConfig)
  191. {
  192.     if(LocalConfig)
  193.     {
  194.         FreeVecPooled(LocalConfig->SpeechFileName);
  195.         FreeVecPooled(LocalConfig->SoundFileName);
  196.         FreeVecPooled(LocalConfig->AreaCodeFileName);
  197.         FreeVecPooled(LocalConfig->PhonebookFileName);
  198.         FreeVecPooled(LocalConfig->HotkeyFileName);
  199.         FreeVecPooled(LocalConfig->TrapFileName);
  200.  
  201.         LocalConfig->SpeechFileName        = NULL;
  202.         LocalConfig->SoundFileName        = NULL;
  203.         LocalConfig->AreaCodeFileName    = NULL;
  204.         LocalConfig->PhonebookFileName    = NULL;
  205.         LocalConfig->HotkeyFileName        = NULL;
  206.         LocalConfig->TrapFileName        = NULL;
  207.     }
  208. }
  209.  
  210. VOID
  211. FinalFix(struct Configuration *LocalConfig,BOOL UnusedIsPhonebook,LONG Version,LONG Revision)
  212. {
  213.     if(LocalConfig)
  214.     {
  215.             /* Ancient compatibility. */
  216.  
  217.         if(LocalConfig->ScreenConfig != NULL)
  218.             LocalConfig->ScreenConfig->StatusLine &= 0xF;
  219.  
  220.         if(Version < 4 || (Version == 4 && Revision < 3))
  221.         {
  222.             if(LocalConfig->TransferConfig && LocalConfig->MiscConfig)
  223.             {
  224.                 LocalConfig->TransferConfig->OverridePath    = LocalConfig->MiscConfig->OverridePath;
  225.                 LocalConfig->TransferConfig->SetArchivedBit    = LocalConfig->MiscConfig->SetArchivedBit;
  226.                 LocalConfig->TransferConfig->IdentifyFiles    = LocalConfig->MiscConfig->IdentifyFiles;
  227.                 LocalConfig->TransferConfig->TransferIcons    = LocalConfig->MiscConfig->TransferIcons;
  228.                 LocalConfig->TransferConfig->PerfMeter        = LocalConfig->MiscConfig->PerfMeter;
  229.                 LocalConfig->TransferConfig->HideUploadIcon    = LocalConfig->MiscConfig->HideUploadIcon;
  230.             }
  231.         }
  232.  
  233.         if(Version < 4 || (Version == 4 && Revision < 3))
  234.         {
  235.             if(LocalConfig->TerminalConfig && LocalConfig->MiscConfig)
  236.                 LocalConfig->MiscConfig->AlertMode = LocalConfig->TerminalConfig->AlertMode;
  237.         }
  238.     }
  239. }
  240.  
  241. VOID
  242. FixOldConfig(struct Configuration *LocalConfig,UBYTE ConfigChunkType,BOOL IsPhonebook,LONG Version,LONG Revision)
  243. {
  244.     if((Version == 3 && Revision < 6) || Version < 3)
  245.     {
  246.         if(ConfigChunkType == PREF_CLIP)
  247.             LocalConfig->ClipConfig->ConvertLF = TRUE;
  248.  
  249.         if(ConfigChunkType == PREF_SERIAL)
  250.             LocalConfig->SerialConfig->UseOwnDevUnit = TRUE;
  251.  
  252.         if(ConfigChunkType == PREF_MISC)
  253.             LocalConfig->MiscConfig->ProtectiveMode = TRUE;
  254.  
  255.         if(ConfigChunkType == PREF_SCREEN)
  256.         {
  257.             LocalConfig->ScreenConfig->UsePens            = TRUE;
  258.             LocalConfig->ScreenConfig->Depth            = 0;
  259.             LocalConfig->ScreenConfig->PenColourMode    = 42;    /* Avoid trouble */
  260.         }
  261.  
  262.         if(ConfigChunkType == PREF_TRANSFER)
  263.         {
  264.             LONG i;
  265.  
  266.             LocalConfig->TransferConfig->MangleFileNames = FALSE;
  267.  
  268.             if(LocalConfig->TransferConfig->ASCIIUploadLibrary[0])
  269.                 LocalConfig->TransferConfig->ASCIIUploadType = XFER_XPR;
  270.  
  271.             if(LocalConfig->TransferConfig->ASCIIDownloadLibrary[0])
  272.                 LocalConfig->TransferConfig->ASCIIDownloadType = XFER_XPR;
  273.  
  274.             if(LocalConfig->TransferConfig->TextUploadLibrary[0])
  275.                 LocalConfig->TransferConfig->TextUploadType = XFER_XPR;
  276.  
  277.             if(LocalConfig->TransferConfig->TextDownloadLibrary[0])
  278.                 LocalConfig->TransferConfig->TextDownloadType = XFER_XPR;
  279.  
  280.             if(LocalConfig->TransferConfig->BinaryUploadLibrary[0])
  281.                 LocalConfig->TransferConfig->BinaryUploadType = XFER_XPR;
  282.  
  283.             if(LocalConfig->TransferConfig->BinaryDownloadLibrary[0])
  284.                 LocalConfig->TransferConfig->BinaryDownloadType = XFER_XPR;
  285.  
  286.             for(i = 0 ; i < strlen(LocalConfig->TransferConfig->DefaultLibrary) - 6 ; i++)
  287.             {
  288.                 if(!Strnicmp(&LocalConfig->TransferConfig->DefaultLibrary[i],"zmodem",6))
  289.                 {
  290.                     strcpy(LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature,"*\030B01");
  291.  
  292.                     LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Length = strlen(LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature);
  293.  
  294.                     break;
  295.                 }
  296.             }
  297.         }
  298.  
  299.         if(ConfigChunkType == PREF_MODEM)
  300.             LocalConfig->ModemConfig->AbortHangsUp = FALSE;
  301.  
  302.         if(ConfigChunkType == PREF_COMMAND && IsPhonebook)
  303.         {
  304.             strcpy(LocalConfig->CommandConfig->LoginMacro,LocalConfig->CommandConfig->StartupMacro);
  305.  
  306.             memset(LocalConfig->CommandConfig->StartupMacro,0,sizeof(LocalConfig->CommandConfig->StartupMacro));
  307.         }
  308.  
  309.         if(ConfigChunkType == PREF_CAPTURE)
  310.             LocalConfig->CaptureConfig->SearchHistory = 10;
  311.  
  312.         if(ConfigChunkType == PREF_EMULATION)
  313.         {
  314.             if(LocalConfig->EmulationConfig->DestructiveBackspace < 0 || LocalConfig->EmulationConfig->DestructiveBackspace > 2)
  315.                 LocalConfig->EmulationConfig->DestructiveBackspace = 1;
  316.         }
  317.     }
  318.  
  319.     if((Version == 4 && Revision < 1) || Version < 4)
  320.     {
  321.         if(ConfigChunkType == PREF_CLIP)
  322.             LocalConfig->ClipConfig->ConvertLF = TRUE;
  323.  
  324.         if(ConfigChunkType == PREF_SERIAL)
  325.         {
  326.             LocalConfig->SerialConfig->xONxOFF        = FALSE;
  327.             LocalConfig->SerialConfig->PassThrough    = TRUE;
  328.         }
  329.  
  330.         if(ConfigChunkType == PREF_MISC)
  331.             LocalConfig->MiscConfig->ProtectiveMode = TRUE;
  332.  
  333.         if(ConfigChunkType == PREF_MODEM)
  334.         {
  335.             LocalConfig->ModemConfig->RedialDelay    = (LocalConfig->ModemConfig->RedialDelay / 6) * 60 + (LocalConfig->ModemConfig->RedialDelay % 6) * 10;
  336.             LocalConfig->ModemConfig->TimeToConnect    = (LocalConfig->ModemConfig->TimeToConnect / 6) * 60 + (LocalConfig->ModemConfig->TimeToConnect % 6) * 10;
  337.             LocalConfig->ModemConfig->VerboseDialing    = FALSE;
  338.         }
  339.  
  340.         if(ConfigChunkType == PREF_TERMINAL)
  341.         {
  342.             switch(LocalConfig->TerminalConfig->SendCR)
  343.             {
  344.                 case CR_IGNORE:
  345.  
  346.                     LocalConfig->TerminalConfig->SendCR = EOL_IGNORE;
  347.                     break;
  348.  
  349.                 case CR_ASCR:
  350.  
  351.                     LocalConfig->TerminalConfig->SendCR = EOL_CR;
  352.                     break;
  353.  
  354.                 case CR_ASCRLF:
  355.  
  356.                     LocalConfig->TerminalConfig->SendCR = EOL_CRLF;
  357.                     break;
  358.             }
  359.  
  360.             switch(LocalConfig->TerminalConfig->ReceiveCR)
  361.             {
  362.                 case CR_IGNORE:
  363.  
  364.                     LocalConfig->TerminalConfig->ReceiveCR = EOL_IGNORE;
  365.                     break;
  366.  
  367.                 case CR_ASCR:
  368.  
  369.                     LocalConfig->TerminalConfig->ReceiveCR = EOL_CR;
  370.                     break;
  371.  
  372.                 case CR_ASCRLF:
  373.  
  374.                     LocalConfig->TerminalConfig->ReceiveCR = EOL_CRLF;
  375.                     break;
  376.             }
  377.  
  378.             switch(LocalConfig->TerminalConfig->SendLF)
  379.             {
  380.                 case LF_IGNORE:
  381.  
  382.                     LocalConfig->TerminalConfig->SendLF = EOL_IGNORE;
  383.                     break;
  384.  
  385.                 case LF_ASLF:
  386.  
  387.                     LocalConfig->TerminalConfig->SendLF = EOL_LF;
  388.                     break;
  389.  
  390.                 case LF_ASLFCR:
  391.  
  392.                     LocalConfig->TerminalConfig->SendLF = EOL_LFCR;
  393.                     break;
  394.             }
  395.  
  396.             switch(LocalConfig->TerminalConfig->ReceiveLF)
  397.             {
  398.                 case LF_IGNORE:
  399.  
  400.                     LocalConfig->TerminalConfig->ReceiveLF = EOL_IGNORE;
  401.                     break;
  402.  
  403.                 case LF_ASLF:
  404.  
  405.                     LocalConfig->TerminalConfig->ReceiveLF = EOL_LF;
  406.                     break;
  407.  
  408.                 case LF_ASLFCR:
  409.  
  410.                     LocalConfig->TerminalConfig->ReceiveLF = EOL_LFCR;
  411.                     break;
  412.             }
  413.         }
  414.  
  415.         if(ConfigChunkType == PREF_TRANSFER)
  416.         {
  417.             LONG i;
  418.  
  419.             if(LocalConfig->TransferConfig->ASCIIUploadLibrary[0])
  420.                 LocalConfig->TransferConfig->ASCIIUploadType = XFER_XPR;
  421.  
  422.             if(LocalConfig->TransferConfig->ASCIIDownloadLibrary[0])
  423.                 LocalConfig->TransferConfig->ASCIIDownloadType = XFER_XPR;
  424.  
  425.             if(LocalConfig->TransferConfig->TextUploadLibrary[0])
  426.                 LocalConfig->TransferConfig->TextUploadType = XFER_XPR;
  427.  
  428.             if(LocalConfig->TransferConfig->TextDownloadLibrary[0])
  429.                 LocalConfig->TransferConfig->TextDownloadType = XFER_XPR;
  430.  
  431.             if(LocalConfig->TransferConfig->BinaryUploadLibrary[0])
  432.                 LocalConfig->TransferConfig->BinaryUploadType = XFER_XPR;
  433.  
  434.             if(LocalConfig->TransferConfig->BinaryDownloadLibrary[0])
  435.                 LocalConfig->TransferConfig->BinaryDownloadType = XFER_XPR;
  436.  
  437.             for(i = 0 ; i < strlen(LocalConfig->TransferConfig->DefaultLibrary) - 6 ; i++)
  438.             {
  439.                 if(!Strnicmp(&LocalConfig->TransferConfig->DefaultLibrary[i],"zmodem",6))
  440.                 {
  441.                     strcpy(LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature,"*\030B01");
  442.  
  443.                     LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Length = strlen(LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature);
  444.  
  445.                     break;
  446.                 }
  447.             }
  448.  
  449.             switch(LocalConfig->TransferConfig->SendCR)
  450.             {
  451.                 case CR_IGNORE:
  452.  
  453.                     LocalConfig->TransferConfig->SendCR = EOL_IGNORE;
  454.                     break;
  455.  
  456.                 case CR_ASCR:
  457.  
  458.                     LocalConfig->TransferConfig->SendCR = EOL_CR;
  459.                     break;
  460.  
  461.                 case CR_ASCRLF:
  462.  
  463.                     LocalConfig->TransferConfig->SendCR = EOL_CRLF;
  464.                     break;
  465.             }
  466.  
  467.             switch(LocalConfig->TransferConfig->ReceiveCR)
  468.             {
  469.                 case CR_IGNORE:
  470.  
  471.                     LocalConfig->TransferConfig->ReceiveCR = EOL_IGNORE;
  472.                     break;
  473.  
  474.                 case CR_ASCR:
  475.  
  476.                     LocalConfig->TransferConfig->ReceiveCR = EOL_CR;
  477.                     break;
  478.  
  479.                 case CR_ASCRLF:
  480.  
  481.                     LocalConfig->TransferConfig->ReceiveCR = EOL_CRLF;
  482.                     break;
  483.             }
  484.  
  485.             switch(LocalConfig->TransferConfig->SendLF)
  486.             {
  487.                 case LF_IGNORE:
  488.  
  489.                     LocalConfig->TransferConfig->SendLF = EOL_IGNORE;
  490.                     break;
  491.  
  492.                 case LF_ASLF:
  493.  
  494.                     LocalConfig->TransferConfig->SendLF = EOL_LF;
  495.                     break;
  496.  
  497.                 case LF_ASLFCR:
  498.  
  499.                     LocalConfig->TransferConfig->SendLF = EOL_LFCR;
  500.                     break;
  501.             }
  502.  
  503.             switch(LocalConfig->TransferConfig->ReceiveLF)
  504.             {
  505.                 case LF_IGNORE:
  506.  
  507.                     LocalConfig->TransferConfig->ReceiveLF = EOL_IGNORE;
  508.                     break;
  509.  
  510.                 case LF_ASLF:
  511.  
  512.                     LocalConfig->TransferConfig->ReceiveLF = EOL_LF;
  513.                     break;
  514.  
  515.                 case LF_ASLFCR:
  516.  
  517.                     LocalConfig->TransferConfig->ReceiveLF = EOL_LFCR;
  518.                     break;
  519.             }
  520.         }
  521.     }
  522.  
  523.     if(Version == 4 && Revision < 3)
  524.     {
  525.         if(ConfigChunkType == PREF_CLIP)
  526.             LocalConfig->ClipConfig->ConvertLF = TRUE;
  527.  
  528.         if(ConfigChunkType == PREF_SERIAL)
  529.         {
  530.             LocalConfig->SerialConfig->xONxOFF        = FALSE;
  531.             LocalConfig->SerialConfig->PassThrough    = TRUE;
  532.         }
  533.  
  534.         if(ConfigChunkType == PREF_MISC)
  535.             LocalConfig->MiscConfig->ProtectiveMode = TRUE;
  536.  
  537.         if(ConfigChunkType == PREF_TRANSFER)
  538.         {
  539.             LONG i;
  540.  
  541.             for(i = 0 ; i < strlen(LocalConfig->TransferConfig->DefaultLibrary) - 6 ; i++)
  542.             {
  543.                 if(!Strnicmp(&LocalConfig->TransferConfig->DefaultLibrary[i],"zmodem",6))
  544.                 {
  545.                     strcpy(LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature,"*\030B01");
  546.  
  547.                     LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Length = strlen(LocalConfig->TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature);
  548.  
  549.                     break;
  550.                 }
  551.             }
  552.  
  553.             if(LocalConfig->TransferConfig->ASCIIUploadLibrary[0])
  554.                 LocalConfig->TransferConfig->ASCIIUploadType = XFER_XPR;
  555.  
  556.             if(LocalConfig->TransferConfig->ASCIIDownloadLibrary[0])
  557.                 LocalConfig->TransferConfig->ASCIIDownloadType = XFER_XPR;
  558.  
  559.             if(LocalConfig->TransferConfig->InternalASCIIUpload)
  560.                 LocalConfig->TransferConfig->ASCIIUploadType = XFER_INTERNAL;
  561.  
  562.             if(LocalConfig->TransferConfig->InternalASCIIDownload)
  563.                 LocalConfig->TransferConfig->ASCIIDownloadType = XFER_INTERNAL;
  564.  
  565.             if(LocalConfig->TransferConfig->TextUploadLibrary[0])
  566.                 LocalConfig->TransferConfig->TextUploadType = XFER_XPR;
  567.  
  568.             if(LocalConfig->TransferConfig->TextDownloadLibrary[0])
  569.                 LocalConfig->TransferConfig->TextDownloadType = XFER_XPR;
  570.  
  571.             if(LocalConfig->TransferConfig->BinaryUploadLibrary[0])
  572.                 LocalConfig->TransferConfig->BinaryUploadType = XFER_XPR;
  573.  
  574.             if(LocalConfig->TransferConfig->BinaryDownloadLibrary[0])
  575.                 LocalConfig->TransferConfig->BinaryDownloadType = XFER_XPR;
  576.         }
  577.     }
  578. }
  579.  
  580. VOID
  581. FixScreenPens(struct ScreenSettings *ScreenConfig)
  582. {
  583.     LONG i,Count;
  584.  
  585.     for(Count = 0, i = DETAILPEN ; i <= BARTRIMPEN ; i++)
  586.     {
  587.         if(ScreenConfig->PenArray[i])
  588.             Count++;
  589.     }
  590.  
  591.     if(!Count)
  592.         ScreenConfig->UsePens = TRUE;
  593. }
  594.  
  595. /*****************************************************************************/
  596.  
  597.     /* ReadSystemPrefs():
  598.      *
  599.      *    Reads the system preferences settings.
  600.      */
  601.  
  602. STATIC BOOL
  603. ReadSystemPrefs(STRPTR Name,ULONG ID,APTR Data,LONG Size,LONG Count)
  604. {
  605.     struct IFFHandle *Handle;
  606.     LONG Error;
  607.  
  608.         /* Allocate an IFF handle. */
  609.  
  610.     if(Handle = OpenIFFStream(Name,MODE_OLDFILE))
  611.     {
  612.             /* Stop at the `body' chunk. */
  613.  
  614.         if(!(Error = StopChunk(Handle,ID_PREF,ID)))
  615.         {
  616.                 /* Look for it... */
  617.  
  618.             while(!ParseIFF(Handle,IFFPARSE_SCAN))
  619.             {
  620.                     /* Read the data. */
  621.  
  622.                 if(ReadIFFBytes(Handle,Data,Size))
  623.                 {
  624.                     if(Count)
  625.                     {
  626.                         Count--;
  627.  
  628.                         Data = (APTR)((ULONG)Data + Size);
  629.                     }
  630.                     else
  631.                         break;
  632.                 }
  633.                 else
  634.                 {
  635.                     Error = IoErr();
  636.  
  637.                     break;
  638.                 }
  639.             }
  640.         }
  641.  
  642.             /* Close the handle. */
  643.  
  644.         CloseIFFStream(Handle);
  645.     }
  646.     else
  647.         Error = IoErr();
  648.  
  649.         /* Return sucess/failure. */
  650.  
  651.     if(Error)
  652.     {
  653.         SetIoErr(Error);
  654.  
  655.         return(FALSE);
  656.     }
  657.     else
  658.         return(TRUE);
  659. }
  660.  
  661. /*****************************************************************************/
  662.  
  663. STATIC VOID
  664. ResetSerialConfig(struct SerialSettings *SerialConfig)
  665. {
  666.     STATIC BOOL                    SerialPrefsRead            = FALSE,
  667.                                 SerialPrefsReadFailed    = FALSE;
  668.     STATIC struct SerialPrefs    SerialPrefs;
  669.  
  670.         /* The program will only try to read the preferences
  671.          * settings once; if the first access failed, no
  672.          * other accesses will be made.
  673.          */
  674.  
  675.     if(!SerialPrefsRead && !SerialPrefsReadFailed)
  676.     {
  677.         if(!ReadSystemPrefs("ENV:sys/serial.prefs",ID_SERL,&SerialPrefs,sizeof(SerialPrefs),1))
  678.             SerialPrefsReadFailed = TRUE;
  679.  
  680.         SerialPrefsRead = TRUE;
  681.     }
  682.  
  683.         /* Did we succeed in reading the file? */
  684.  
  685.     if(SerialPrefsRead && !SerialPrefsReadFailed)
  686.     {
  687.             /* Fill in the common data. */
  688.  
  689.         SerialConfig->BaudRate            = SerialPrefs.sp_BaudRate;
  690.         SerialConfig->SerialBufferSize    = SerialPrefs.sp_InputBuffer;
  691.         SerialConfig->BitsPerChar        = SerialPrefs.sp_BitsPerChar;
  692.         SerialConfig->StopBits            = SerialPrefs.sp_StopBits;
  693.  
  694.             /* Convert the handshaking mode. */
  695.  
  696.         switch(SerialPrefs.sp_InputHandshake)
  697.         {
  698.             case HSHAKE_NONE:
  699.  
  700.                 SerialConfig->HandshakingProtocol = HANDSHAKING_NONE;
  701.  
  702.                 break;
  703.  
  704.             case HSHAKE_RTS:
  705.  
  706.                 SerialConfig->HandshakingProtocol = HANDSHAKING_RTSCTS_DSR;
  707.  
  708.                 break;
  709.  
  710.             default:
  711.  
  712.                 SerialConfig->HandshakingProtocol = HANDSHAKING_NONE;
  713.  
  714.                 break;
  715.         }
  716.  
  717.             /* Convert the parity settings. */
  718.  
  719.         if(SerialPrefs.sp_Parity <= PARITY_SPACE)
  720.             SerialConfig->Parity = SerialPrefs.sp_Parity;
  721.         else
  722.             SerialConfig->Parity = PARITY_NONE;
  723.     }
  724.     else
  725.     {
  726.         SerialConfig->BaudRate                = 19200;
  727.         SerialConfig->BitsPerChar            = 8;
  728.         SerialConfig->Parity                = PARITY_NONE;
  729.         SerialConfig->StopBits                = 1;
  730.         SerialConfig->HandshakingProtocol    = HANDSHAKING_RTSCTS_DSR;
  731.         SerialConfig->SerialBufferSize        = 32768;
  732.     }
  733.  
  734.     strcpy(SerialConfig->SerialDevice,SERIALNAME);
  735.  
  736.     SerialConfig->Duplex                = DUPLEX_FULL;
  737.     SerialConfig->BreakLength            = 250000;
  738.     SerialConfig->UnitNumber            = 0;
  739.     SerialConfig->PassThrough            = TRUE;
  740.  
  741.     SerialConfig->Quantum                = 256;
  742.  
  743.     SerialConfig->SatisfyODURequests    = ODU_RELEASE;
  744. }
  745.  
  746. STATIC VOID
  747. ResetModem(struct ModemSettings *ModemConfig)
  748. {
  749.     strcpy(ModemConfig->ModemInit,            "ATX3E1V1Q0\\r");
  750.     strcpy(ModemConfig->ModemExit,            "");
  751.     strcpy(ModemConfig->ModemHangup,        "~~~~+++~~~~ATH0\\r");
  752.     strcpy(ModemConfig->DialPrefix,            "ATD\\w");
  753.     strcpy(ModemConfig->DialSuffix,            "\\r");
  754.  
  755.     strcpy(ModemConfig->NoCarrier,            "NO CARRIER");
  756.     strcpy(ModemConfig->NoDialTone,            "NO DIALTONE");
  757.     strcpy(ModemConfig->Connect,            "CONNECT");
  758.     strcpy(ModemConfig->Voice,                "VOICE");
  759.     strcpy(ModemConfig->Ring,                "RING");
  760.     strcpy(ModemConfig->Busy,                "BUSY");
  761.     strcpy(ModemConfig->Ok,                    "OK");
  762.     strcpy(ModemConfig->Error,                "ERROR");
  763.  
  764.     ModemConfig->RedialDelay                = 20;
  765.     ModemConfig->DialRetries                = 10;
  766.     ModemConfig->DialTimeout                = 60;
  767.  
  768.     ModemConfig->NoCarrierIsBusy            = TRUE;
  769.  
  770.     ModemConfig->DialMode                    = DIALMODE_PULSE;
  771.  
  772.     strcpy(ModemConfig->PBX_Prefix,            "0,,,");
  773.  
  774.     strcpy(ModemConfig->NoCarrier,            "NO ANSWER");
  775. }
  776.  
  777. STATIC VOID
  778. ResetScreen(struct ScreenSettings *ScreenConfig)
  779. {
  780.     struct Screen *PubScreen;
  781.     ULONG DisplayID;
  782.  
  783.     if(!FontPrefsRead && !FontPrefsReadFailed)
  784.     {
  785.         if(!ReadSystemPrefs("ENV:sys/font.prefs",ID_FONT,FontPrefs,sizeof(struct FontPrefs),3))
  786.             FontPrefsReadFailed = TRUE;
  787.  
  788.         FontPrefsRead = TRUE;
  789.     }
  790.  
  791.     DisplayID = INVALID_ID;
  792.  
  793.     strcpy(ScreenConfig->FontName,"topaz.font");
  794.     ScreenConfig->FontHeight = 8;
  795.  
  796.     if(FontPrefsRead && !FontPrefsReadFailed)
  797.     {
  798.         LONG i;
  799.  
  800.         for(i = 0 ; i < 3 ; i++)
  801.         {
  802.             if(FontPrefs[i].fp_Type == FP_SCREENFONT)
  803.             {
  804.                 strcpy(ScreenConfig->FontName,FontPrefs[i].fp_Name);
  805.                 ScreenConfig->FontHeight = FontPrefs[i].fp_TextAttr.ta_YSize;
  806.  
  807.                 break;
  808.             }
  809.         }
  810.     }
  811.  
  812.     if(DisplayID == INVALID_ID)
  813.     {
  814.         if(PubScreen = LockPubScreen(NULL))
  815.         {
  816.             DisplayID = GetVPModeID(&PubScreen->ViewPort);
  817.  
  818.             UnlockPubScreen(NULL,PubScreen);
  819.         }
  820.         else
  821.             DisplayID = DEFAULT_MONITOR_ID | HIRESLACE_KEY;
  822.     }
  823.  
  824.     ScreenConfig->DisplayMode        = DisplayID;
  825.     ScreenConfig->ColourMode        = COLOUR_AMIGA;
  826.     ScreenConfig->MakeScreenPublic    = TRUE;
  827.     ScreenConfig->TitleBar            = TRUE;
  828.     ScreenConfig->StatusLine        = STATUSLINE_STANDARD;
  829.     ScreenConfig->Blinking            = TRUE;
  830.  
  831.     ScreenConfig->TimeMode            = ONLINETIME_BOTH;
  832.     ScreenConfig->UsePens            = TRUE;
  833.     ScreenConfig->PenColourMode        = COLOUR_AMIGA;
  834.  
  835.     ScreenConfig->OverscanType        = OSCAN_TEXT;
  836. }
  837.  
  838. STATIC VOID
  839. ResetTerminal(struct TerminalSettings *TerminalConfig)
  840. {
  841.     if(!FontPrefsRead && !FontPrefsReadFailed)
  842.     {
  843.         if(!ReadSystemPrefs("ENV:sys/font.prefs",ID_FONT,FontPrefs,sizeof(struct FontPrefs),3))
  844.             FontPrefsReadFailed = TRUE;
  845.  
  846.         FontPrefsRead = TRUE;
  847.     }
  848.  
  849.     strcpy(TerminalConfig->TextFontName,"topaz.font");
  850.     TerminalConfig->TextFontHeight = 8;
  851.  
  852.     strcpy(TerminalConfig->IBMFontName,"IBM.font");
  853.     TerminalConfig->IBMFontHeight = 8;
  854.  
  855.     if(FontPrefsRead && !FontPrefsReadFailed)
  856.     {
  857.         LONG i;
  858.  
  859.         for(i = 0 ; i < 3 ; i++)
  860.         {
  861.             if(FontPrefs[i].fp_Type == FP_SYSFONT)
  862.             {
  863.                 strcpy(TerminalConfig->TextFontName,FontPrefs[i].fp_Name);
  864.                 TerminalConfig->TextFontHeight = FontPrefs[i].fp_TextAttr.ta_YSize;
  865.  
  866.                 if(TerminalConfig->TextFontHeight == 8 || TerminalConfig->TextFontHeight == 11)
  867.                     TerminalConfig->IBMFontHeight = TerminalConfig->TextFontHeight;
  868.  
  869.                 break;
  870.             }
  871.         }
  872.     }
  873.  
  874.     TerminalConfig->BellMode        = BELL_AUDIBLE;
  875.     TerminalConfig->AlertMode        = ALERT_BEEP_SCREEN;
  876.     TerminalConfig->EmulationMode    = EMULATION_ANSIVT100;
  877.     TerminalConfig->FontMode        = FONT_STANDARD;
  878.  
  879.     TerminalConfig->SendCR            = EOL_CR;
  880.     TerminalConfig->SendLF            = EOL_LF;
  881.     TerminalConfig->ReceiveCR        = EOL_CR;
  882.     TerminalConfig->ReceiveLF        = EOL_LF;
  883. }
  884.  
  885. STATIC VOID
  886. ResetEmulation(struct EmulationSettings *EmulationConfig)
  887. {
  888.     LONG i;
  889.  
  890.     EmulationConfig->CursorMode            = KEYMODE_STANDARD;
  891.     EmulationConfig->NumericMode        = KEYMODE_STANDARD;
  892.  
  893.     EmulationConfig->LineWrap            = TRUE;
  894.  
  895.     EmulationConfig->FontScale            = SCALE_NORMAL;
  896.     EmulationConfig->ScrollMode            = SCROLL_JUMP;
  897.     EmulationConfig->PrinterEnabled        = TRUE;
  898.     EmulationConfig->MaxJump            = 1;
  899.  
  900.     EmulationConfig->UseStandardPens    = TRUE;
  901.  
  902.     for(i = TEXTATTR_UNDERLINE ; i <= TEXTATTR_INVERSE ; i++)
  903.         EmulationConfig->Attributes[i] = i;
  904.  
  905.     for(i = 0 ; i < 16 ; i++)
  906.         EmulationConfig->Pens[i] = i;
  907.  
  908.     EmulationConfig->TerminalType = TERMINAL_VT200;
  909. }
  910.  
  911. STATIC VOID
  912. ResetClip(struct ClipSettings *ClipConfig)
  913. {
  914.     strcpy(ClipConfig->InsertSuffix,"\\r");
  915.  
  916.     ClipConfig->PacingMode        = PACE_DIRECT;
  917.     ClipConfig->ConvertLF        = TRUE;
  918. }
  919.  
  920. STATIC VOID
  921. ResetCapture(struct CaptureSettings *CaptureConfig)
  922. {
  923.     CaptureConfig->BufferEnabled        = TRUE;
  924.  
  925.     CaptureConfig->CaptureFilterMode    = FILTER_BOTH;
  926.  
  927.     CaptureConfig->AutoCaptureDate        = AUTOCAPTURE_DATE_NAME;
  928.     CaptureConfig->SearchHistory        = 10;
  929.  
  930.     CaptureConfig->OpenBufferWindow        = BUFFER_END;
  931.     CaptureConfig->OpenBufferScreen        = BUFFER_TOP;
  932.     CaptureConfig->BufferScreenPosition    = SCREEN_CENTRE;
  933.     CaptureConfig->BufferWidth            = 80;
  934.  
  935.     CaptureConfig->BufferScreenMode        = INVALID_ID;
  936.  
  937.     CaptureConfig->BufferMode            = BUFFERMODE_FLOW;
  938.  
  939.     CaptureConfig->LogFileFormat        = LOGFILEFORMAT_CallInfo;
  940.  
  941.     CaptureConfig->BufferSafetyMemory    = 60 * 1024;
  942. }
  943.  
  944. STATIC VOID
  945. ResetTranslationFile(STRPTR Here,STRPTR PathBuffer)
  946. {
  947.     if(!PathBuffer)
  948.         PathBuffer = "TERM:config";
  949.  
  950.     if(!LastTranslation[0])
  951.     {
  952.         strcpy(LastTranslation,PathBuffer);
  953.  
  954.         AddPart(LastTranslation,"translation.prefs",MAX_FILENAME_LENGTH);
  955.     }
  956.  
  957.     strcpy(Here,LastTranslation);
  958. }
  959.  
  960. STATIC VOID
  961. ResetMacroFile(STRPTR Here,STRPTR PathBuffer)
  962. {
  963.     if(!PathBuffer)
  964.         PathBuffer = "TERM:config";
  965.  
  966.     if(!LastMacros[0])
  967.     {
  968.         strcpy(LastMacros,PathBuffer);
  969.  
  970.         AddPart(LastMacros,"functionkeys.prefs",MAX_FILENAME_LENGTH);
  971.     }
  972.  
  973.     strcpy(Here,LastMacros);
  974. }
  975.  
  976. STATIC VOID
  977. ResetCursorFile(STRPTR Here,STRPTR PathBuffer)
  978. {
  979.     if(!PathBuffer)
  980.         PathBuffer = "TERM:config";
  981.  
  982.     if(!LastCursorKeys[0])
  983.     {
  984.         strcpy(LastCursorKeys,PathBuffer);
  985.  
  986.         AddPart(LastCursorKeys,"cursorkeys.prefs",MAX_FILENAME_LENGTH);
  987.     }
  988.  
  989.     strcpy(Here,LastCursorKeys);
  990. }
  991.  
  992. STATIC VOID
  993. ResetFastMacroFile(STRPTR Here,STRPTR PathBuffer)
  994. {
  995.     if(!PathBuffer)
  996.         PathBuffer = "TERM:config";
  997.  
  998.     if(!LastFastMacros[0])
  999.     {
  1000.         strcpy(LastFastMacros,PathBuffer);
  1001.  
  1002.         AddPart(LastFastMacros,"fastmacros.prefs",MAX_FILENAME_LENGTH);
  1003.     }
  1004.  
  1005.     strcpy(Here,LastFastMacros);
  1006. }
  1007.  
  1008. STATIC VOID
  1009. ResetSpeechFile(STRPTR Here,STRPTR PathBuffer)
  1010. {
  1011.     if(!PathBuffer)
  1012.         PathBuffer = "TERM:config";
  1013.  
  1014.     if(!LastSpeech[0])
  1015.     {
  1016.         strcpy(LastSpeech,PathBuffer);
  1017.  
  1018.         AddPart(LastSpeech,"speech.prefs",MAX_FILENAME_LENGTH);
  1019.     }
  1020.  
  1021.     strcpy(Here,LastSpeech);
  1022. }
  1023.  
  1024. STATIC VOID
  1025. ResetSoundFile(STRPTR Here,STRPTR PathBuffer)
  1026. {
  1027.     if(!PathBuffer)
  1028.         PathBuffer = "TERM:config";
  1029.  
  1030.     if(!LastSound[0])
  1031.     {
  1032.         strcpy(LastSound,PathBuffer);
  1033.  
  1034.         AddPart(LastSound,"sound.prefs",MAX_FILENAME_LENGTH);
  1035.     }
  1036.  
  1037.     strcpy(Here,LastSound);
  1038. }
  1039.  
  1040. STATIC VOID
  1041. ResetAreaCodeFile(STRPTR Here,STRPTR PathBuffer)
  1042. {
  1043.     if(!PathBuffer)
  1044.         PathBuffer = "TERM:config";
  1045.  
  1046.     if(!LastPattern[0])
  1047.     {
  1048.         strcpy(LastPattern,PathBuffer);
  1049.  
  1050.         AddPart(LastPattern,"rates.prefs",MAX_FILENAME_LENGTH);
  1051.     }
  1052.  
  1053.     strcpy(Here,LastPattern);
  1054. }
  1055.  
  1056. STATIC VOID
  1057. ResetPhonebookFile(STRPTR Here,STRPTR PathBuffer)
  1058. {
  1059.     if(!PathBuffer)
  1060.         PathBuffer = "TERM:config";
  1061.  
  1062.     if(!LastPhone[0])
  1063.     {
  1064.         strcpy(LastPhone,PathBuffer);
  1065.  
  1066.         AddPart(LastPhone,"phonebook.prefs",MAX_FILENAME_LENGTH);
  1067.     }
  1068.  
  1069.     strcpy(Here,LastPhone);
  1070. }
  1071.  
  1072. STATIC VOID
  1073. ResetHotkeyFile(STRPTR Here,STRPTR PathBuffer)
  1074. {
  1075.     if(!PathBuffer)
  1076.         PathBuffer = "TERM:config";
  1077.  
  1078.     if(!LastKeys[0])
  1079.     {
  1080.         strcpy(LastKeys,PathBuffer);
  1081.  
  1082.         AddPart(LastKeys,"hotkeys.prefs",MAX_FILENAME_LENGTH);
  1083.     }
  1084.  
  1085.     strcpy(Here,LastKeys);
  1086. }
  1087.  
  1088. STATIC VOID
  1089. ResetTrapFile(STRPTR Here,STRPTR PathBuffer)
  1090. {
  1091.     if(!PathBuffer)
  1092.         PathBuffer = "TERM:config";
  1093.  
  1094.     if(!LastTraps[0])
  1095.     {
  1096.         strcpy(LastTraps,PathBuffer);
  1097.  
  1098.         AddPart(LastTraps,"trap.prefs",MAX_FILENAME_LENGTH);
  1099.     }
  1100.  
  1101.     strcpy(Here,LastTraps);
  1102. }
  1103.  
  1104. STATIC VOID
  1105. ResetFile(struct FileSettings *FileConfig,STRPTR PathBuffer)
  1106. {
  1107.     if(!PathBuffer)
  1108.         PathBuffer = "TERM:config";
  1109.  
  1110.     strcpy(FileConfig->ProtocolFileName,"xprzmodem.library");
  1111.  
  1112.     if(!LastTranslation[0])
  1113.     {
  1114.         strcpy(LastTranslation,PathBuffer);
  1115.  
  1116.         AddPart(LastTranslation,"translation.prefs",MAX_FILENAME_LENGTH);
  1117.     }
  1118.  
  1119.     strcpy(FileConfig->TranslationFileName,LastTranslation);
  1120.  
  1121.     if(!LastMacros[0])
  1122.     {
  1123.         strcpy(LastMacros,PathBuffer);
  1124.  
  1125.         AddPart(LastMacros,"functionkeys.prefs",MAX_FILENAME_LENGTH);
  1126.     }
  1127.  
  1128.     strcpy(FileConfig->MacroFileName,LastMacros);
  1129.  
  1130.     if(!LastFastMacros[0])
  1131.     {
  1132.         strcpy(LastFastMacros,PathBuffer);
  1133.  
  1134.         AddPart(LastFastMacros,"fastmacros.prefs",MAX_FILENAME_LENGTH);
  1135.     }
  1136.  
  1137.     strcpy(FileConfig->FastMacroFileName,LastFastMacros);
  1138.  
  1139.     if(!LastCursorKeys[0])
  1140.     {
  1141.         strcpy(LastCursorKeys,PathBuffer);
  1142.  
  1143.         AddPart(LastCursorKeys,"cursorkeys.prefs",MAX_FILENAME_LENGTH);
  1144.     }
  1145.  
  1146.     strcpy(FileConfig->CursorFileName,LastCursorKeys);
  1147. }
  1148.  
  1149. STATIC VOID
  1150. ResetPath(struct PathSettings *PathConfig,STRPTR PathBuffer)
  1151. {
  1152.     if(!PathBuffer)
  1153.         PathBuffer = "TERM:config";
  1154.  
  1155.     strcpy(PathConfig->DefaultStorage,PathBuffer);
  1156.  
  1157.     strcpy(PathConfig->HelpFile,"PROGDIR:term.guide");
  1158.  
  1159.     strcpy(PathConfig->DefaultStorage,PathBuffer);
  1160.  
  1161.     GetEnvDOS("EDITOR",PathConfig->Editor,sizeof(PathConfig->Editor));
  1162. }
  1163.  
  1164. STATIC VOID
  1165. ResetMisc(struct MiscSettings *MiscConfig)
  1166. {
  1167.     MiscConfig->Priority            = 1;
  1168.  
  1169.     MiscConfig->ReleaseDevice        = TRUE;
  1170.  
  1171.     MiscConfig->TransferServer        = TRUE;
  1172.     MiscConfig->EmulationServer        = TRUE;
  1173.  
  1174.     MiscConfig->OverridePath        = TRUE;
  1175.     MiscConfig->AutoUpload            = TRUE;
  1176.     MiscConfig->IdentifyFiles        = IDENTIFY_FILETYPE;
  1177.  
  1178.     MiscConfig->IOBufferSize        = 32768;
  1179.  
  1180.     MiscConfig->ProtectiveMode        = TRUE;
  1181.  
  1182.     MiscConfig->AlertMode            = ALERT_BEEP_SCREEN;
  1183.     MiscConfig->RequesterMode        = REQUESTERMODE_IGNORE;
  1184.  
  1185.     strcpy(MiscConfig->WaitString," \\b");
  1186.  
  1187.     MiscConfig->WaitDelay            = 1;    /* Just one second */
  1188.  
  1189.     if(!GetEnvDOS("TERMWINDOW",MiscConfig->WindowName,sizeof(MiscConfig->WindowName)))
  1190.         strcpy(MiscConfig->WindowName,"CON:0/11//100/term Output Window/CLOSE/SCREEN %s");
  1191. }
  1192.  
  1193. STATIC VOID
  1194. ResetCommand(struct CommandSettings *UnusedCommandConfig)
  1195. {
  1196. }
  1197.  
  1198. STATIC VOID
  1199. ResetTransfer(struct TransferSettings *TransferConfig,STRPTR DefaultLib)
  1200. {
  1201.     LONG i;
  1202.  
  1203.     if(!DefaultLib)
  1204.         strcpy(TransferConfig->DefaultLibrary,"xprzmodem.library");
  1205.     else
  1206.         strcpy(TransferConfig->DefaultLibrary,DefaultLib);
  1207.  
  1208.     for(i = 0 ; i < strlen(TransferConfig->DefaultLibrary) - 6 ; i++)
  1209.     {
  1210.         if(!Strnicmp(&TransferConfig->DefaultLibrary[i],"zmodem",6))
  1211.         {
  1212.             strcpy(TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature,"*\030B01");
  1213.  
  1214.             TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Length = strlen(TransferConfig->Signatures[TRANSFERSIG_DEFAULTUPLOAD].Signature);
  1215.  
  1216.             break;
  1217.         }
  1218.     }
  1219.  
  1220.     strcpy(TransferConfig->ASCIIUploadLibrary,        "xprascii.library");
  1221.     strcpy(TransferConfig->ASCIIDownloadLibrary,    "xprascii.library");
  1222.  
  1223.     strcpy(TransferConfig->BinaryUploadLibrary,"run hydracom device %p speed %b line %c nocarrier rec %> send %m");
  1224.     strcpy(TransferConfig->BinaryDownloadLibrary,"run hydracom device %p speed %b line %c nocarrier rec %> get");
  1225.  
  1226.     TransferConfig->PacingMode                = PACE_DIRECT;
  1227.     TransferConfig->IgnoreDataPastArnold    = TRUE;
  1228.     TransferConfig->TerminatorChar            = 0x1A;
  1229.     TransferConfig->SendCR                    = EOL_CR;
  1230.     TransferConfig->SendLF                    = EOL_LF;
  1231.     TransferConfig->ReceiveCR                = EOL_CR;
  1232.     TransferConfig->ReceiveLF                = EOL_LF;
  1233.  
  1234.     TransferConfig->ErrorNotification        = 20;
  1235.     TransferConfig->TransferNotification    = XFERNOTIFY_ALWAYS;
  1236.  
  1237.     TransferConfig->DefaultType                = XFER_XPR;
  1238.     TransferConfig->ASCIIDownloadType        = XFER_XPR;
  1239.     TransferConfig->ASCIIUploadType            = XFER_XPR;
  1240.     TransferConfig->TextDownloadType        = XFER_DEFAULT;
  1241.     TransferConfig->TextUploadType            = XFER_DEFAULT;
  1242.     TransferConfig->BinaryDownloadType        = XFER_DEFAULT;
  1243.     TransferConfig->BinaryUploadType        = XFER_DEFAULT;
  1244.  
  1245.     TransferConfig->OverridePath            = TRUE;
  1246.     TransferConfig->IdentifyFiles            = IDENTIFY_FILETYPE;
  1247. }
  1248.  
  1249. /*****************************************************************************/
  1250.  
  1251. STATIC BOOL
  1252. WriteConfigChunk(struct IFFHandle *Handle,struct Configuration *LocalConfig,LONG Type,APTR TempBuffer,STRPTR Password)
  1253. {
  1254.     if(Type >= PREF_SERIAL && Type < PREF_RATES && Type != PREF_FILE)
  1255.     {
  1256.         APTR Data;
  1257.         LONG Error;
  1258.  
  1259.         if(Data = GetConfigEntry(LocalConfig,Type))
  1260.         {
  1261.             if(TempBuffer)
  1262.             {
  1263.                 Encrypt(Data,SizeTable[Type - PREF_SERIAL],TempBuffer,Password,MAX_PASSWORD_LENGTH);
  1264.  
  1265.                 Data = TempBuffer;
  1266.             }
  1267.  
  1268.             Error = AddIFFChunkBytes(Handle,TypeTable[Type - PREF_SERIAL],Data,SizeTable[Type - PREF_SERIAL]);
  1269.             if(Error != OK)
  1270.             {
  1271.                 SetIoErr(Error);
  1272.  
  1273.                 return(FALSE);
  1274.             }
  1275.         }
  1276.     }
  1277.  
  1278.     return(TRUE);
  1279. }
  1280.  
  1281. STATIC LONG
  1282. IsConfigChunk(ULONG ID)
  1283. {
  1284.     LONG Type;
  1285.  
  1286.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1287.     {
  1288.         if(ID == TypeTable[Type - PREF_SERIAL])
  1289.             return(Type);
  1290.     }
  1291.  
  1292.     return(0);
  1293. }
  1294.  
  1295. STATIC BOOL
  1296. WriteConfigChunks(struct IFFHandle *Handle,struct Configuration *LocalConfig,APTR TempBuffer,STRPTR Password)
  1297. {
  1298.     LONG Type;
  1299.  
  1300.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1301.     {
  1302.         if(!WriteConfigChunk(Handle,LocalConfig,Type,TempBuffer,Password))
  1303.             return(FALSE);
  1304.     }
  1305.  
  1306.     return(TRUE);
  1307. }
  1308.  
  1309. STATIC VOID
  1310. ResetNewConfigEntry(APTR To,LONG Type)
  1311. {
  1312.     if(Type >= PREF_SERIAL && Type < PREF_RATES)
  1313.     {
  1314.         LONG Size;
  1315.         APTR From;
  1316.  
  1317.         From = GetConfigEntry(Config,Type);
  1318.         Size = SizeTable[Type - PREF_SERIAL];
  1319.  
  1320.         if(From)
  1321.             CopyMem(From,To,Size);
  1322.         else
  1323.         {
  1324.             memset(To,0,Size);
  1325.  
  1326.             (*ResetTable[Type - PREF_SERIAL])(To,NULL);
  1327.         }
  1328.  
  1329.         if(Type == PREF_SCREEN)
  1330.             FixScreenPens(To);
  1331.     }
  1332. }
  1333.  
  1334. STATIC BOOL
  1335. ClosePhonebookFile(struct IFFHandle *Handle)
  1336. {
  1337.     LONG Error;
  1338.  
  1339.     Error = PopChunk(Handle);
  1340.  
  1341.     if(!CloseIFFStream(Handle))
  1342.     {
  1343.         if(!Error)
  1344.             Error = IoErr();
  1345.     }
  1346.  
  1347.     if(Error)
  1348.     {
  1349.         SetIoErr(Error);
  1350.  
  1351.         return(FALSE);
  1352.     }
  1353.     else
  1354.         return(TRUE);
  1355. }
  1356.  
  1357. STATIC struct IFFHandle *
  1358. CreatePhonebookFile(STRPTR Name,PhonebookHandle *PhoneHandle)
  1359. {
  1360.     struct IFFHandle *Handle;
  1361.  
  1362.     if(Handle = OpenIFFStream(Name,MODE_NEWFILE))
  1363.     {
  1364.         LONG Error;
  1365.  
  1366.         if(!(Error = PushChunk(Handle,ID_TERM,ID_CAT,IFFSIZE_UNKNOWN)))
  1367.         {
  1368.             if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  1369.             {
  1370.                 struct TermInfo TermInfo;
  1371.  
  1372.                 TermInfo.Version    = CONFIG_FILE_VERSION;
  1373.                 TermInfo.Revision    = CONFIG_FILE_REVISION;
  1374.  
  1375.                 Error = AddIFFChunkBytes(Handle,ID_VERS,&TermInfo,sizeof(struct TermInfo));
  1376.  
  1377.                 if(!Error && PhoneHandle->PhonePasswordUsed)
  1378.                 {
  1379.                     Error = AddIFFChunkBytes(Handle,ID_PSWD,PhoneHandle->PhonePassword,MAX_PASSWORD_LENGTH);
  1380.                 }
  1381.  
  1382.                 if(!Error)
  1383.                 {
  1384.                     PhonebookGlobals Globals;
  1385.  
  1386.                     Globals.Count            = PhoneHandle->NumPhoneEntries;
  1387.                     Globals.ID                = PhoneHandle->PhonebookID;
  1388.                     Globals.DefaultGroup    = PhoneHandle->DefaultGroup;
  1389.                     Globals.AutoDial        = PhoneHandle->AutoDial;
  1390.                     Globals.AutoExit        = PhoneHandle->AutoExit;
  1391.  
  1392.                     Error = AddIFFChunkBytes(Handle,ID_DIAL,&Globals,sizeof(Globals));
  1393.                 }
  1394.  
  1395.                 if(!Error)
  1396.                     Error = PopChunk(Handle);
  1397.             }
  1398.         }
  1399.  
  1400.         if(Error)
  1401.         {
  1402.             CloseIFFStream(Handle);
  1403.             DeleteFile(Name);
  1404.  
  1405.             SetIoErr(Error);
  1406.  
  1407.             return(NULL);
  1408.         }
  1409.         else
  1410.             return(Handle);
  1411.     }
  1412.     else
  1413.         return(NULL);
  1414. }
  1415.  
  1416. STATIC BOOL
  1417. DumpPhonebookRates(struct IFFHandle *Handle,struct PhoneEntry *Entry)
  1418. {
  1419.     struct TimeDateNode *TimeDateNode;
  1420.     LONG Error;
  1421.  
  1422.     Error = 0;
  1423.  
  1424.     for(TimeDateNode = (struct TimeDateNode *)Entry->TimeDateList.mlh_Head ; !Error && TimeDateNode->Node.ln_Succ ; TimeDateNode = (struct TimeDateNode *)TimeDateNode->Node.ln_Succ)
  1425.     {
  1426.         if(!(Error = PushChunk(Handle,0,ID_DAT2,IFFSIZE_UNKNOWN)))
  1427.         {
  1428.             if(!WriteIFFBytes(Handle,&TimeDateNode->Header,sizeof(struct TimeDateHeader)))
  1429.                 return(FALSE);
  1430.             else
  1431.             {
  1432.                 if(!WriteIFFRecords(Handle,TimeDateNode->Table,sizeof(struct TimeDate),TimeDateNode->Table[0].Count))
  1433.                     return(FALSE);
  1434.             }
  1435.  
  1436.             Error = PopChunk(Handle);
  1437.         }
  1438.     }
  1439.  
  1440.     if(Error)
  1441.     {
  1442.         SetIoErr(Error);
  1443.  
  1444.         return(FALSE);
  1445.     }
  1446.     else
  1447.         return(TRUE);
  1448. }
  1449.  
  1450. STATIC BOOL
  1451. DumpPhonebookGroups(struct IFFHandle *Handle,struct List *GroupList)
  1452. {
  1453.     if(!IsListEmpty(GroupList))
  1454.     {
  1455.         struct PhoneGroupNode *GroupNode;
  1456.         struct PhoneNode *Node;
  1457.         PhoneGroupHeader Header;
  1458.         BOOL FormOpen;
  1459.         LONG Error;
  1460.  
  1461.         FormOpen = FALSE;
  1462.  
  1463.             /* So the extension stuff is set to zero */
  1464.  
  1465.         memset(&Header,0,sizeof(Header));
  1466.  
  1467.             /* Run down the groups */
  1468.  
  1469.         for(GroupNode = (PhoneGroupNode *)GroupList->lh_Head ; GroupNode->Node.ln_Succ ; GroupNode = (PhoneGroupNode *)GroupNode->Node.ln_Succ)
  1470.         {
  1471.                 /* Count the members */
  1472.  
  1473.             Header.Count = GetListSize((struct List *)&GroupNode->GroupList);
  1474.  
  1475.                 /* Open the group */
  1476.  
  1477.             if(Header.Count > 0)
  1478.             {
  1479.                 if(!FormOpen)
  1480.                 {
  1481.                     if(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN))
  1482.                     {
  1483.                         SetIoErr(Error);
  1484.  
  1485.                         return(FALSE);
  1486.                     }
  1487.  
  1488.                     FormOpen = TRUE;
  1489.                 }
  1490.  
  1491.                     /* Pick up the group name */
  1492.  
  1493.                 strcpy(Header.FullName,GroupNode->LocalName);
  1494.  
  1495.                 if(Error = PushChunk(Handle,0,ID_GRUP,sizeof(Header) + sizeof(LONG) * Header.Count))
  1496.                 {
  1497.                     SetIoErr(Error);
  1498.  
  1499.                     return(FALSE);
  1500.                 }
  1501.                 else
  1502.                 {
  1503.                         /* First the header... */
  1504.  
  1505.                     if(WriteIFFBytes(Handle,&Header,sizeof(Header)))
  1506.                     {
  1507.                             /* ...then the IDs of the group members */
  1508.  
  1509.                         for(Node = (struct PhoneNode *)GroupNode->GroupList.mlh_Head ; Node->Node.ln_Succ ; Node = (struct PhoneNode *)Node->Node.ln_Succ)
  1510.                         {
  1511.                             if(!WriteIFFBytes(Handle,&Node->Entry->Header->ID,sizeof(ULONG)))
  1512.                                 return(FALSE);
  1513.                         }
  1514.                     }
  1515.                     else
  1516.                         return(FALSE);
  1517.  
  1518.                     if(Error = PopChunk(Handle))
  1519.                     {
  1520.                         SetIoErr(Error);
  1521.  
  1522.                         return(FALSE);
  1523.                     }
  1524.                 }
  1525.             }
  1526.         }
  1527.  
  1528.         if(FormOpen)
  1529.         {
  1530.             if(Error = PopChunk(Handle))
  1531.             {
  1532.                 SetIoErr(Error);
  1533.  
  1534.                 return(FALSE);
  1535.             }
  1536.         }
  1537.     }
  1538.  
  1539.     return(TRUE);
  1540. }
  1541.  
  1542. STATIC BOOL
  1543. DumpPhonebookFile(struct IFFHandle *Handle,APTR TempBuffer,PhonebookHandle *PhoneHandle)
  1544. {
  1545.     PhoneEntry **Phonebook;
  1546.     STRPTR Password;
  1547.     APTR Whatever;
  1548.     APTR Stuff;
  1549.     LONG Error;
  1550.     LONG i;
  1551.  
  1552.     Error = 0;
  1553.  
  1554.     if(TempBuffer)
  1555.     {
  1556.         Password    = PhoneHandle->PhonePassword;
  1557.         Stuff        = TempBuffer;
  1558.     }
  1559.     else
  1560.     {
  1561.         Password    = NULL;
  1562.         Stuff        = NULL;
  1563.     }
  1564.  
  1565.     Phonebook = PhoneHandle->Phonebook;
  1566.  
  1567.     for(i = 0 ; !Error && i < PhoneHandle->NumPhoneEntries ; i++)
  1568.     {
  1569.         if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  1570.         {
  1571.                 /* New feature for v4.7: store the dialing order in the phoneheader. */
  1572.  
  1573.             if(Phonebook[i]->Count < 0)
  1574.                 Phonebook[i]->Header->Marked = 0;
  1575.             else
  1576.                 Phonebook[i]->Header->Marked = Phonebook[i]->Count + 1;
  1577.  
  1578.             if(TempBuffer)
  1579.             {
  1580.                 Encrypt((UBYTE *)Phonebook[i]->Header,sizeof(PhoneHeader),TempBuffer,PhoneHandle->PhonePassword,MAX_PASSWORD_LENGTH);
  1581.  
  1582.                 Whatever = TempBuffer;
  1583.             }
  1584.             else
  1585.             {
  1586.                 Whatever = Phonebook[i]->Header;
  1587.             }
  1588.  
  1589.             Error = AddIFFChunkBytes(Handle,ID_PHON,Whatever,sizeof(PhoneHeader));
  1590.             if(!Error)
  1591.             {
  1592.                 if(WriteConfigChunks(Handle,Phonebook[i]->Config,Stuff,Password))
  1593.                 {
  1594.                     if(!Phonebook[i]->Header->NoRates)
  1595.                     {
  1596.                         if(!DumpPhonebookRates(Handle,Phonebook[i]))
  1597.                             return(FALSE);
  1598.                     }
  1599.                 }
  1600.                 else
  1601.                 {
  1602.                     return(FALSE);
  1603.                 }
  1604.             }
  1605.  
  1606.             if(!Error)
  1607.                 Error = PopChunk(Handle);
  1608.         }
  1609.     }
  1610.  
  1611.         /* Now for the groups */
  1612.  
  1613.     if(!Error)
  1614.     {
  1615.         if(!DumpPhonebookGroups(Handle,(struct List *)&PhoneHandle->PhoneGroupList))
  1616.             Error = IoErr();
  1617.     }
  1618.  
  1619.     if(Error)
  1620.     {
  1621.         SetIoErr(Error);
  1622.         return(FALSE);
  1623.     }
  1624.     else
  1625.         return(TRUE);
  1626. }
  1627.  
  1628. STATIC BOOL
  1629. ReadConfigChunk(struct IFFHandle *Handle,struct Configuration *LocalConfig,LONG Type,LONG Len,STRPTR Password)
  1630. {
  1631.     if(CreateConfigEntry(LocalConfig,Type))
  1632.     {
  1633.         APTR Data;
  1634.  
  1635.         Data = GetConfigEntry(LocalConfig,Type);
  1636.  
  1637.         Len = MIN(SizeTable[Type - PREF_SERIAL],Len);
  1638.  
  1639.         if(ReadIFFBytes(Handle,Data,Len))
  1640.         {
  1641.             if(Password)
  1642.                 Decrypt(Data,Len,Data,Password,MAX_PASSWORD_LENGTH);
  1643.  
  1644.             if(Type == PREF_SCREEN)
  1645.                 FixScreenPens(Data);
  1646.  
  1647.             return(TRUE);
  1648.         }
  1649.     }
  1650.  
  1651.     return(FALSE);
  1652. }
  1653.  
  1654. STATIC APTR *
  1655. GetConfigEntryPointer(struct Configuration *LocalConfig,LONG Type)
  1656. {
  1657.     APTR *Mem;
  1658.  
  1659.     switch(Type)
  1660.     {
  1661.         case PREF_SERIAL:
  1662.  
  1663.             Mem = (APTR *)&LocalConfig->SerialConfig;
  1664.             break;
  1665.  
  1666.         case PREF_MODEM:
  1667.  
  1668.             Mem = (APTR *)&LocalConfig->ModemConfig;
  1669.             break;
  1670.  
  1671.         case PREF_COMMAND:
  1672.  
  1673.             Mem = (APTR *)&LocalConfig->CommandConfig;
  1674.             break;
  1675.  
  1676.         case PREF_SCREEN:
  1677.  
  1678.             Mem = (APTR *)&LocalConfig->ScreenConfig;
  1679.             break;
  1680.  
  1681.         case PREF_TERMINAL:
  1682.  
  1683.             Mem = (APTR *)&LocalConfig->TerminalConfig;
  1684.             break;
  1685.  
  1686.         case PREF_PATH:
  1687.  
  1688.             Mem = (APTR *)&LocalConfig->PathConfig;
  1689.             break;
  1690.  
  1691.         case PREF_MISC:
  1692.  
  1693.             Mem = (APTR *)&LocalConfig->MiscConfig;
  1694.             break;
  1695.  
  1696.         case PREF_CLIP:
  1697.  
  1698.             Mem = (APTR *)&LocalConfig->ClipConfig;
  1699.             break;
  1700.  
  1701.         case PREF_CAPTURE:
  1702.  
  1703.             Mem = (APTR *)&LocalConfig->CaptureConfig;
  1704.             break;
  1705.  
  1706.         case PREF_FILE:
  1707.  
  1708.             Mem = (APTR *)&LocalConfig->FileConfig;
  1709.             break;
  1710.  
  1711.         case PREF_EMULATION:
  1712.  
  1713.             Mem = (APTR *)&LocalConfig->EmulationConfig;
  1714.             break;
  1715.  
  1716.         case PREF_TRANSFER:
  1717.  
  1718.             Mem = (APTR *)&LocalConfig->TransferConfig;
  1719.             break;
  1720.  
  1721.         case PREF_TRANSLATIONFILENAME:
  1722.  
  1723.             Mem = (APTR *)&LocalConfig->TranslationFileName;
  1724.             break;
  1725.  
  1726.         case PREF_MACROFILENAME:
  1727.  
  1728.             Mem = (APTR *)&LocalConfig->MacroFileName;
  1729.             break;
  1730.  
  1731.         case PREF_CURSORFILENAME:
  1732.  
  1733.             Mem = (APTR *)&LocalConfig->CursorFileName;
  1734.             break;
  1735.  
  1736.         case PREF_FASTMACROFILENAME:
  1737.  
  1738.             Mem = (APTR *)&LocalConfig->FastMacroFileName;
  1739.             break;
  1740.  
  1741.         case PREF_SPEECHFILENAME:
  1742.  
  1743.             Mem = (APTR *)&LocalConfig->SpeechFileName;
  1744.             break;
  1745.  
  1746.         case PREF_SOUNDFILENAME:
  1747.  
  1748.             Mem = (APTR *)&LocalConfig->SoundFileName;
  1749.             break;
  1750.  
  1751.         case PREF_AREACODEFILENAME:
  1752.  
  1753.             Mem = (APTR *)&LocalConfig->AreaCodeFileName;
  1754.             break;
  1755.  
  1756.         case PREF_PHONEBOOKFILENAME:
  1757.  
  1758.             Mem = (APTR *)&LocalConfig->PhonebookFileName;
  1759.             break;
  1760.  
  1761.         case PREF_HOTKEYFILENAME:
  1762.  
  1763.             Mem = (APTR *)&LocalConfig->HotkeyFileName;
  1764.             break;
  1765.  
  1766.         case PREF_TRAPFILENAME:
  1767.  
  1768.             Mem = (APTR *)&LocalConfig->TrapFileName;
  1769.             break;
  1770.  
  1771.         default:
  1772.  
  1773.             Mem = NULL;
  1774.             break;
  1775.     }
  1776.  
  1777.     return(Mem);
  1778. }
  1779.  
  1780.     /* ResetConfig():
  1781.      *
  1782.      *    Initialize configuration with default values.
  1783.      */
  1784.  
  1785. VOID
  1786. ResetConfig(struct Configuration *LocalConfig,STRPTR PathBuffer)
  1787. {
  1788.     STRPTR Arg;
  1789.     LONG Type;
  1790.     APTR Data;
  1791.  
  1792.     if(!PathBuffer)
  1793.         PathBuffer = "TERM:config";
  1794.  
  1795.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1796.     {
  1797.         if(Data = GetConfigEntry(LocalConfig,Type))
  1798.         {
  1799.             memset(Data,0,SizeTable[Type - PREF_SERIAL]);
  1800.  
  1801.             switch(Type)
  1802.             {
  1803.                 case PREF_PATH:
  1804.                 case PREF_FILE:
  1805.                 case PREF_TRANSLATIONFILENAME:
  1806.                 case PREF_MACROFILENAME:
  1807.                 case PREF_CURSORFILENAME:
  1808.                 case PREF_FASTMACROFILENAME:
  1809.                 case PREF_SPEECHFILENAME:
  1810.                 case PREF_SOUNDFILENAME:
  1811.                 case PREF_AREACODEFILENAME:
  1812.                 case PREF_PHONEBOOKFILENAME:
  1813.                 case PREF_HOTKEYFILENAME:
  1814.                 case PREF_TRAPFILENAME:
  1815.  
  1816.                     Arg = PathBuffer;
  1817.                     break;
  1818.  
  1819.                 case PREF_TRANSFER:
  1820.  
  1821.                     if(LocalConfig->FileConfig)
  1822.                         Arg = LocalConfig->FileConfig->ProtocolFileName;
  1823.                     else
  1824.                         Arg = "xprzmodem.library";
  1825.  
  1826.                     break;
  1827.  
  1828.                 default:
  1829.  
  1830.                     Arg = NULL;
  1831.                     break;
  1832.             }
  1833.  
  1834.             (*ResetTable[Type - PREF_SERIAL])(Data,Arg);
  1835.         }
  1836.     }
  1837. }
  1838.  
  1839. VOID
  1840. DeleteConfigEntry(struct Configuration *LocalConfig,LONG Type)
  1841. {
  1842.     if(Type == PREF_ALL)
  1843.     {
  1844.         for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1845.             DeleteConfigEntry(LocalConfig,Type);
  1846.     }
  1847.     else
  1848.     {
  1849.         APTR *Mem;
  1850.  
  1851.         if(Mem = GetConfigEntryPointer(LocalConfig,Type))
  1852.         {
  1853.             FreeVecPooled(*Mem);
  1854.  
  1855.             *Mem = NULL;
  1856.         }
  1857.     }
  1858. }
  1859.  
  1860. VOID
  1861. ResetConfigEntry(struct Configuration *LocalConfig,LONG Type)
  1862. {
  1863.     if(LocalConfig && Type >= PREF_SERIAL && Type < PREF_RATES)
  1864.     {
  1865.         APTR To;
  1866.  
  1867.         if(To = GetConfigEntry(LocalConfig,Type))
  1868.             ResetNewConfigEntry(To,Type);
  1869.     }
  1870. }
  1871.  
  1872. APTR
  1873. GetConfigEntry(struct Configuration *LocalConfig,LONG Type)
  1874. {
  1875.     if(LocalConfig)
  1876.     {
  1877.         APTR *Mem;
  1878.  
  1879.         if(Mem = GetConfigEntryPointer(LocalConfig,Type))
  1880.             return(*Mem);
  1881.     }
  1882.  
  1883.     return(NULL);
  1884. }
  1885.  
  1886. LONG
  1887. CompareConfigEntries(APTR a,APTR b,LONG Type)
  1888. {
  1889.     LONG Result;
  1890.  
  1891.     if(Type < PREF_SERIAL || Type >= PREF_RATES || a == b)
  1892.         Result = 0;
  1893.     else
  1894.         Result = memcmp(a,b,SizeTable[Type - PREF_SERIAL]);
  1895.  
  1896.     return(Result);
  1897. }
  1898.  
  1899. VOID
  1900. PutConfigEntry(struct Configuration *LocalConfig,APTR Data,LONG Type)
  1901. {
  1902.     if(LocalConfig && Data && Type >= PREF_SERIAL && Type < PREF_RATES)
  1903.     {
  1904.         APTR Destination;
  1905.  
  1906.         if(Destination = GetConfigEntry(LocalConfig,Type))
  1907.         {
  1908.             if(Data != Destination)
  1909.                 CopyMem(Data,Destination,SizeTable[Type - PREF_SERIAL]);
  1910.         }
  1911.     }
  1912. }
  1913.  
  1914. VOID
  1915. CopyConfigEntry(struct Configuration *LocalConfig,LONG Type,APTR Data)
  1916. {
  1917.     if(LocalConfig && Data && Type >= PREF_SERIAL && Type < PREF_RATES)
  1918.     {
  1919.         APTR Source;
  1920.  
  1921.         if(Source = GetConfigEntry(LocalConfig,Type))
  1922.         {
  1923.             if(Source != Data)
  1924.                 CopyMem(Source,Data,SizeTable[Type - PREF_SERIAL]);
  1925.         }
  1926.     }
  1927. }
  1928.  
  1929. APTR
  1930. CreateNewConfigEntry(LONG Type)
  1931. {
  1932.     APTR Data;
  1933.  
  1934.     Data = NULL;
  1935.  
  1936.     if(Type >= PREF_SERIAL && Type < PREF_RATES)
  1937.     {
  1938.         if(Data = AllocVecPooled(SizeTable[Type - PREF_SERIAL],MEMF_ANY | MEMF_CLEAR))
  1939.             ResetNewConfigEntry(Data,Type);
  1940.     }
  1941.  
  1942.     return(Data);
  1943. }
  1944.  
  1945. BOOL
  1946. CreateConfigEntry(struct Configuration *LocalConfig,LONG Type)
  1947. {
  1948.     if(Type == PREF_ALL)
  1949.     {
  1950.         for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  1951.         {
  1952.             if(!CreateConfigEntry(LocalConfig,Type))
  1953.             {
  1954.                 DeleteConfigEntry(LocalConfig,PREF_ALL);
  1955.                 return(FALSE);
  1956.             }
  1957.         }
  1958.  
  1959.         return(TRUE);
  1960.     }
  1961.     else
  1962.     {
  1963.         if(Type >= PREF_SERIAL && Type < PREF_RATES)
  1964.         {
  1965.             APTR *Mem;
  1966.  
  1967.             if(Mem = GetConfigEntryPointer(LocalConfig,Type))
  1968.             {
  1969.                 if(*Mem)
  1970.                     return(TRUE);
  1971.                 else
  1972.                 {
  1973.                     if(*Mem = CreateNewConfigEntry(Type))
  1974.                         return(TRUE);
  1975.                 }
  1976.             }
  1977.         }
  1978.  
  1979.         return(FALSE);
  1980.     }
  1981. }
  1982.  
  1983. VOID
  1984. DeleteConfiguration(struct Configuration *LocalConfig)
  1985. {
  1986.     if(LocalConfig)
  1987.     {
  1988.         DeleteConfigEntry(LocalConfig,PREF_ALL);
  1989.  
  1990.         FreeVecPooled(LocalConfig);
  1991.     }
  1992. }
  1993.  
  1994. struct Configuration *
  1995. CreateConfiguration(BOOL Fill)
  1996. {
  1997.     struct Configuration *LocalConfig;
  1998.  
  1999.     if(LocalConfig = (struct Configuration *)AllocVecPooled(sizeof(struct Configuration),MEMF_ANY | MEMF_CLEAR))
  2000.     {
  2001.         if(Fill)
  2002.         {
  2003.             if(!CreateConfigEntry(LocalConfig,PREF_ALL))
  2004.             {
  2005.                 FreeVecPooled(LocalConfig);
  2006.  
  2007.                 return(NULL);
  2008.             }
  2009.         }
  2010.  
  2011.         return(LocalConfig);
  2012.     }
  2013.     else
  2014.         return(NULL);
  2015. }
  2016.  
  2017. VOID
  2018. SaveConfig(struct Configuration *Src,struct Configuration *Dst)
  2019. {
  2020.     APTR From,To;
  2021.     LONG Type;
  2022.  
  2023.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  2024.     {
  2025.         From    = GetConfigEntry(Src,Type);
  2026.         To        = GetConfigEntry(Dst,Type);
  2027.  
  2028.         if(From && To)
  2029.         {
  2030.             CopyMem(From,To,SizeTable[Type - PREF_SERIAL]);
  2031.  
  2032.             if(Type == PREF_SCREEN)
  2033.                 FixScreenPens(To);
  2034.         }
  2035.     }
  2036. }
  2037.  
  2038. VOID
  2039. SwapConfig(struct Configuration *Src,struct Configuration *Dst)
  2040. {
  2041.     APTR From,To;
  2042.     LONG Type;
  2043.  
  2044.     for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  2045.     {
  2046.         From    = GetConfigEntry(Src,Type);
  2047.         To        = GetConfigEntry(Dst,Type);
  2048.  
  2049.         if(From && To)
  2050.             SwapMem(From,To,SizeTable[Type - PREF_SERIAL]);
  2051.     }
  2052. }
  2053.  
  2054. BOOL
  2055. SavePhonebook(STRPTR Name,PhonebookHandle *PhoneHandle)
  2056. {
  2057.     if(PhoneHandle->Phonebook && PhoneHandle->NumPhoneEntries > 0)
  2058.     {
  2059.         struct IFFHandle *Handle;
  2060.         LONG Error;
  2061.  
  2062.         if(!(Handle = CreatePhonebookFile(Name,PhoneHandle)))
  2063.             Error = IoErr();
  2064.         else
  2065.         {
  2066.             APTR TempBuffer;
  2067.  
  2068.             TempBuffer = NULL;
  2069.             Error = 0;
  2070.  
  2071.             if(PhoneHandle->PhonePasswordUsed)
  2072.             {
  2073.                 LONG Max = sizeof(PhoneHeader);
  2074.                 LONG Type;
  2075.  
  2076.                 for(Type = PREF_SERIAL ; Type < PREF_RATES ; Type++)
  2077.                 {
  2078.                     if(SizeTable[Type - PREF_SERIAL] > Max)
  2079.                         Max = SizeTable[Type - PREF_SERIAL];
  2080.                 }
  2081.  
  2082.                 if(!(TempBuffer = AllocVecPooled(Max,MEMF_ANY)))
  2083.                     Error = ERROR_NO_FREE_STORE;
  2084.             }
  2085.  
  2086.             if(!Error)
  2087.             {
  2088.                 if(!DumpPhonebookFile(Handle,TempBuffer,PhoneHandle))
  2089.                     Error = IoErr();
  2090.             }
  2091.  
  2092.             FreeVecPooled(TempBuffer);
  2093.  
  2094.             if(!ClosePhonebookFile(Handle))
  2095.             {
  2096.                 if(!Error)
  2097.                     Error = IoErr();
  2098.             }
  2099.  
  2100.             if(Error)
  2101.                 DeleteFile(Name);
  2102.         }
  2103.  
  2104.         if(Error)
  2105.         {
  2106.             SetIoErr(Error);
  2107.  
  2108.             return(FALSE);
  2109.         }
  2110.     }
  2111.  
  2112.     return(TRUE);
  2113. }
  2114.  
  2115.     /* LoadPhonebook(STRPTR Name):
  2116.      *
  2117.      *    Restore a phone book from a disk file.
  2118.      */
  2119.  
  2120. PhonebookHandle *
  2121. LoadPhonebook(STRPTR Name)
  2122. {
  2123.     struct PhoneEntry        **Phonebook;
  2124.     struct IFFHandle        *Handle;
  2125.     struct ContextNode        *Chunk;
  2126.     UBYTE                     ConfigChunkType;
  2127.     LONG                     Error;
  2128.     PhonebookHandle            *PhoneHandle;
  2129.     struct PhonebookGlobals     Globals;
  2130.     struct PhoneGroupHeader     GroupHeader;
  2131.     struct Configuration    *LocalConfig;
  2132.     LONG                     i;
  2133.     struct TermInfo             TermInfo;
  2134.     BOOL                     FirstChunk;
  2135.     BOOL                     CheckedChunk;
  2136.     BOOL                     GotID;
  2137.     LONG                     Index;
  2138.     LONG                     Size;
  2139.     UBYTE                     PasswordBuffer[MAX_PASSWORD_LENGTH];
  2140.     BOOL                     UsePhonePassword;
  2141.  
  2142.     PhoneHandle         = NULL;
  2143.     FirstChunk            = TRUE;
  2144.     CheckedChunk        = FALSE;
  2145.     GotID                = FALSE;
  2146.     Index                = 0;
  2147.     UsePhonePassword    = FALSE;
  2148.  
  2149.     if(Handle = OpenIFFStream(Name,MODE_OLDFILE))
  2150.     {
  2151.         if(!(Error = StopChunks(Handle,Stops,NUM_STOPS)))
  2152.         {
  2153.             while(!ParseIFF(Handle,IFFPARSE_SCAN))
  2154.             {
  2155.                 Chunk = CurrentChunk(Handle);
  2156.  
  2157.                     /* Is this the first chunk to be read? */
  2158.  
  2159.                 if(!CheckedChunk)
  2160.                 {
  2161.                     CheckedChunk = TRUE;
  2162.  
  2163.                         /* The first chunk must be a
  2164.                          * catalog chunk, or this would
  2165.                          * not be a proper phonebook file.
  2166.                          */
  2167.  
  2168.                     if(Chunk->cn_ID != ID_CAT)
  2169.                     {
  2170.                         Error = ERROR_OBJECT_WRONG_TYPE;
  2171.  
  2172.                         break;
  2173.                     }
  2174.                 }
  2175.  
  2176.                 switch(Chunk->cn_ID)
  2177.                 {
  2178.                     case ID_VERS:
  2179.  
  2180.                         memset(&TermInfo,0,sizeof(TermInfo));
  2181.  
  2182.                         if(ReadIFFBytes(Handle,&TermInfo,sizeof(struct TermInfo)))
  2183.                         {
  2184.                             if(TermInfo.Version != CONFIG_FILE_VERSION || (TermInfo.Version == CONFIG_FILE_VERSION && TermInfo.Revision > CONFIG_FILE_REVISION))
  2185.                             {
  2186.                                 if(TermInfo.Version == 2 && TermInfo.Revision == 4)
  2187.                                 {
  2188.                                     CloseIFFStream(Handle);
  2189.  
  2190.                                     return(LoadOldPhonebook(Name));
  2191.                                 }
  2192.                                 else
  2193.                                 {
  2194.                                     if(TermInfo.Version != 3)
  2195.                                         Error = ERROR_OBJECT_WRONG_TYPE;
  2196.                                 }
  2197.                             }
  2198.                         }
  2199.                         else
  2200.                             Error = IoErr();
  2201.  
  2202.                         break;
  2203.  
  2204.                     case ID_PSWD:
  2205.  
  2206.                         if(ReadIFFBytes(Handle,PasswordBuffer,MAX_PASSWORD_LENGTH))
  2207.                         {
  2208.                             BOOL AskPassword = TRUE;
  2209.  
  2210.                             if(GlobalPhoneHandle->PhonePasswordUsed)
  2211.                             {
  2212.                                 if(!memcmp(GlobalPhoneHandle->PhonePassword,PasswordBuffer,MAX_PASSWORD_LENGTH))
  2213.                                 {
  2214.                                     UsePhonePassword    = TRUE;
  2215.                                     AskPassword            = FALSE;
  2216.                                 }
  2217.                             }
  2218.  
  2219.                             if(AskPassword)
  2220.                             {
  2221.                                 UBYTE LocalBuffer[MAX_PASSWORD_LENGTH+1];
  2222.                                 BOOL Ok;
  2223.  
  2224.                                 memset(LocalBuffer,0,sizeof(LocalBuffer));
  2225.                                 Ok = FALSE;
  2226.  
  2227.                                 if(GetString(FALSE,TRUE,sizeof(LocalBuffer),LocaleString(MSG_PHONEPANEL_PLEASE_ENTER_PASSWORD_TXT),LocalBuffer))
  2228.                                 {
  2229.                                     UBYTE AnotherBuffer[MAX_PASSWORD_LENGTH];
  2230.  
  2231.                                     Encrypt(LocalBuffer,MAX_PASSWORD_LENGTH,AnotherBuffer,LocalBuffer,strlen(LocalBuffer));
  2232.  
  2233.                                     if(!memcmp(PasswordBuffer,AnotherBuffer,MAX_PASSWORD_LENGTH))
  2234.                                     {
  2235.                                         UsePhonePassword    = TRUE;
  2236.                                         Ok                    = TRUE;
  2237.                                     }
  2238.                                 }
  2239.  
  2240.                                 if(!Ok)
  2241.                                 {
  2242.                                     ShowRequest(Window,LocaleString(MSG_TERMPHONE_WRONG_PASSWORD_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Name);
  2243.  
  2244.                                     Error = ERROR_REQUIRED_ARG_MISSING;
  2245.                                 }
  2246.                             }
  2247.                         }
  2248.                         else
  2249.                             Error = IoErr();
  2250.  
  2251.                         break;
  2252.  
  2253.                     case ID_DIAL:
  2254.  
  2255.                         Size = MIN(sizeof(Globals),Chunk->cn_Size);
  2256.  
  2257.                         memset(&Globals,0,sizeof(Globals));
  2258.  
  2259.                         if(ReadIFFBytes(Handle,&Globals,Size))
  2260.                         {
  2261.                             if(Globals.Count > 0)
  2262.                             {
  2263.                                 if(!(PhoneHandle = CreatePhonebook(Globals.Count,TRUE)))
  2264.                                     Error = ERROR_NO_FREE_STORE;
  2265.                                 else
  2266.                                 {
  2267.                                     if(Size >= sizeof(PhonebookGlobals))
  2268.                                     {
  2269.                                         PhoneHandle->PhonebookID    = Globals.ID;
  2270.                                         PhoneHandle->DefaultGroup    = Globals.DefaultGroup;
  2271.                                         PhoneHandle->AutoDial        = Globals.AutoDial;
  2272.                                         PhoneHandle->AutoExit        = Globals.AutoExit;
  2273.  
  2274.                                         GotID = TRUE;
  2275.                                     }
  2276.                                     else
  2277.                                     {
  2278.                                         struct timeval Now;
  2279.  
  2280.                                         GetSysTime(&Now);
  2281.  
  2282.                                         PhoneHandle->PhonebookID    = Now.tv_secs;
  2283.                                         PhoneHandle->DefaultGroup    = 0;
  2284.                                         PhoneHandle->AutoDial        = FALSE;
  2285.                                         PhoneHandle->AutoExit        = FALSE;
  2286.  
  2287.                                         GotID = FALSE;
  2288.                                     }
  2289.  
  2290.                                     if(UsePhonePassword)
  2291.                                     {
  2292.                                         PhoneHandle->PhonePasswordUsed = TRUE;
  2293.                                         CopyMem(PasswordBuffer,PhoneHandle->PhonePassword,MAX_PASSWORD_LENGTH);
  2294.                                     }
  2295.  
  2296.                                     Phonebook = PhoneHandle->Phonebook;
  2297.                                 }
  2298.                             }
  2299.                         }
  2300.                         else
  2301.                             Error = IoErr();
  2302.  
  2303.                         break;
  2304.  
  2305.                     case ID_PHON:
  2306.  
  2307.                         Size = MIN(sizeof(PhoneHeader),Chunk->cn_Size);
  2308.  
  2309.                         if(FirstChunk)
  2310.                             FirstChunk = FALSE;
  2311.                         else
  2312.                             Index++;
  2313.  
  2314.                         memset(Phonebook[Index]->Header,0,sizeof(PhoneHeader));
  2315.  
  2316.                         if(ReadIFFBytes(Handle,Phonebook[Index]->Header,Size))
  2317.                         {
  2318.                             if(PhoneHandle->PhonePasswordUsed)
  2319.                                 Decrypt((UBYTE *)Phonebook[Index]->Header,Size,(UBYTE *)Phonebook[Index]->Header,PhoneHandle->PhonePassword,MAX_PASSWORD_LENGTH);
  2320.  
  2321.                             if(!GotID)
  2322.                                 Phonebook[Index]->Header->ID = PhoneHandle->PhonebookID++;
  2323.                         }
  2324.                         else
  2325.                             Error = IoErr();
  2326.  
  2327.                         break;
  2328.  
  2329.                         /* Mucho importante -- must follow the phonebook entries */
  2330.  
  2331.                     case ID_GRUP:
  2332.  
  2333.                         if(!Phonebook[PhoneHandle->NumPhoneEntries - 1])
  2334.                         {
  2335.                             Error = ERR_LOAD_ERROR;
  2336.                             break;
  2337.                         }
  2338.  
  2339.                         DB(kprintf("--> ID_GRUP\n"));
  2340.  
  2341.                         if(ReadIFFBytes(Handle,&GroupHeader,sizeof(GroupHeader)))
  2342.                         {
  2343.                             PhoneGroupNode *GroupNode;
  2344.                             ULONG ID;
  2345.  
  2346.                             GroupNode = NULL;
  2347.  
  2348.                             DB(kprintf("group name |%s| entries %ld\n",GroupHeader.FullName,GroupHeader.Count));
  2349.  
  2350.                             for(i = 0 ; !Error && i < GroupHeader.Count ; i++)
  2351.                             {
  2352.                                 if(ReadIFFBytes(Handle,&ID,sizeof(ULONG)))
  2353.                                 {
  2354.                                     LONG j;
  2355.  
  2356.                                     DB(kprintf("looking for 0x%08lx\n",ID));
  2357.  
  2358.                                     for(j = 0 ; j < PhoneHandle->NumPhoneEntries ; j++)
  2359.                                     {
  2360.                                         if(Phonebook[j]->Header->ID == ID)
  2361.                                         {
  2362.                                             DB(kprintf("found it |%s|\n",Phonebook[j]->Header->Name));
  2363.  
  2364.                                             if(!GroupNode)
  2365.                                                 GroupNode = CreatePhoneGroup(PhoneHandle,GroupHeader.FullName);
  2366.  
  2367.                                             if(!GroupNode)
  2368.                                             {
  2369.                                                 Error = ERROR_NO_FREE_STORE;
  2370.  
  2371.                                                 break;
  2372.                                             }
  2373.  
  2374.                                             if(!AddGroupEntry(GroupNode,Phonebook[j]))
  2375.                                             {
  2376.                                                 Error = ERROR_NO_FREE_STORE;
  2377.  
  2378.                                                 break;
  2379.                                             }
  2380.                                         }
  2381.                                     }
  2382.                                 }
  2383.                                 else
  2384.                                 {
  2385.                                     Error = IoErr();
  2386.  
  2387.                                     break;
  2388.                                 }
  2389.                             }
  2390.                         }
  2391.                         else
  2392.                             Error = IoErr();
  2393.  
  2394.                         break;
  2395.  
  2396.                     /* Special treatment for obsolete "FILE" chunk */
  2397.  
  2398.                     case ID_FILE:
  2399.  
  2400.                         LocalConfig = Phonebook[Index]->Config;
  2401.  
  2402.                         for(i = PREF_TRANSLATIONFILENAME ; !Error && i < PREF_RATES ; i++)
  2403.                         {
  2404.                             if(!CreateConfigEntry(LocalConfig,i))
  2405.                                 Error = ERROR_NO_FREE_STORE;
  2406.                         }
  2407.  
  2408.                         if(!Error)
  2409.                         {
  2410.                             strcpy(LocalConfig->TranslationFileName,    LocalConfig->FileConfig->TranslationFileName);
  2411.                             strcpy(LocalConfig->MacroFileName,        LocalConfig->FileConfig->MacroFileName);
  2412.                             strcpy(LocalConfig->CursorFileName,        LocalConfig->FileConfig->CursorFileName);
  2413.                             strcpy(LocalConfig->FastMacroFileName,    LocalConfig->FileConfig->FastMacroFileName);
  2414.  
  2415.                             DeleteConfigEntry(LocalConfig,PREF_FILE);
  2416.                         }
  2417.  
  2418.                         break;
  2419.  
  2420.                     case ID_DATE:
  2421.  
  2422.                         if(!Phonebook[Index]->Header->NoRates)
  2423.                         {
  2424.                             LONG Count = (Chunk->cn_Size - sizeof(struct TimeDateHeader)) / sizeof(struct TimeDateOld);
  2425.                             struct TimeDateNode *TimeDateNode;
  2426.  
  2427.                             if(TimeDateNode = CreateTimeDateNode(-1,-1,"",Count))
  2428.                             {
  2429.                                 struct TimeDateOld *Old;
  2430.  
  2431.                                 if(Old = (struct TimeDateOld *)AllocVecPooled(sizeof(struct TimeDateOld) * Count,MEMF_ANY))
  2432.                                 {
  2433.                                     if(ReadIFFBytes(Handle,&TimeDateNode->Header,sizeof(struct TimeDateHeader)))
  2434.                                     {
  2435.                                         if(ReadIFFRecords(Handle,Old,sizeof(struct TimeDateOld),Count))
  2436.                                         {
  2437.                                             for(i = 0 ; i < Count ; i++)
  2438.                                                 ConvertTimeDate(&Old[i],&TimeDateNode->Table[i]);
  2439.  
  2440.                                             AdaptTimeDateNode(TimeDateNode);
  2441.  
  2442.                                             AddTail((struct List *)&Phonebook[Index]->TimeDateList,&TimeDateNode->Node);
  2443.  
  2444.                                             TimeDateNode = NULL;
  2445.                                         }
  2446.                                         else
  2447.                                             Error = IoErr();
  2448.                                     }
  2449.                                     else
  2450.                                         Error = IoErr();
  2451.  
  2452.                                     FreeVecPooled(Old);
  2453.                                 }
  2454.                                 else
  2455.                                     Error = ERROR_NO_FREE_STORE;
  2456.  
  2457.                                 FreeTimeDateNode(TimeDateNode);
  2458.                             }
  2459.                             else
  2460.                                 Error = ERROR_NO_FREE_STORE;
  2461.                         }
  2462.  
  2463.                         break;
  2464.  
  2465.                     case ID_DAT2:
  2466.  
  2467.                         if(!Phonebook[Index]->Header->NoRates)
  2468.                         {
  2469.                             LONG Count = (Chunk->cn_Size - sizeof(struct TimeDateHeader)) / sizeof(struct TimeDate);
  2470.                             struct TimeDateNode *TimeDateNode;
  2471.  
  2472.                             if(TimeDateNode = CreateTimeDateNode(-1,-1,"",Count))
  2473.                             {
  2474.                                 if(ReadIFFBytes(Handle,&TimeDateNode->Header,sizeof(struct TimeDateHeader)))
  2475.                                 {
  2476.                                     if(ReadIFFRecords(Handle,TimeDateNode->Table,sizeof(struct TimeDate),Count))
  2477.                                     {
  2478.                                         AdaptTimeDateNode(TimeDateNode);
  2479.  
  2480.                                         AddTail((struct List *)&Phonebook[Index]->TimeDateList,&TimeDateNode->Node);
  2481.  
  2482.                                         TimeDateNode = NULL;
  2483.                                     }
  2484.                                     else
  2485.                                         Error = IoErr();
  2486.                                 }
  2487.                                 else
  2488.                                     Error = IoErr();
  2489.  
  2490.                                 FreeTimeDateNode(TimeDateNode);
  2491.                             }
  2492.                             else
  2493.                                 Error = IoErr();
  2494.                         }
  2495.  
  2496.                         break;
  2497.  
  2498.                     default:
  2499.  
  2500.                         if(ConfigChunkType = IsConfigChunk(Chunk->cn_ID))
  2501.                         {
  2502.                             if(ReadConfigChunk(Handle,Phonebook[Index]->Config,ConfigChunkType,Chunk->cn_Size,PhoneHandle->PhonePasswordUsed ? PhoneHandle->PhonePassword : NULL))
  2503.                                 FixOldConfig(Phonebook[Index]->Config,ConfigChunkType,TRUE,TermInfo.Version,TermInfo.Revision);
  2504.                             else
  2505.                                 Error = IoErr();
  2506.                         }
  2507.  
  2508.                         break;
  2509.                 }
  2510.  
  2511.                 if(Error)
  2512.                     break;
  2513.             }
  2514.  
  2515.             if(!Error && PhoneHandle)
  2516.             {
  2517.                 if(!Phonebook[PhoneHandle->NumPhoneEntries - 1])
  2518.                     Error = ERR_LOAD_ERROR;
  2519.             }
  2520.  
  2521.             if(!Error)
  2522.             {
  2523.                 for(i = 0 ; i < PhoneHandle->NumPhoneEntries ; i++)
  2524.                 {
  2525.                     FinalFix(Phonebook[i]->Config,TRUE,TermInfo.Version,TermInfo.Revision);
  2526.                     StripGlobals(Phonebook[i]->Config);
  2527.                 }
  2528.             }
  2529.         }
  2530.  
  2531.         CloseIFFStream(Handle);
  2532.     }
  2533.     else
  2534.         Error = IoErr();
  2535.  
  2536.     if(Error)
  2537.     {
  2538.         if(PhoneHandle)
  2539.             DeletePhonebook(PhoneHandle);
  2540.  
  2541.         SetIoErr(Error);
  2542.  
  2543.         return(NULL);
  2544.     }
  2545.     else
  2546.         return(PhoneHandle);
  2547. }
  2548.  
  2549.     /* WriteConfig(STRPTR Name,struct Configuration *LocalConfig):
  2550.      *
  2551.      *    Write the configuration to a file, very much like
  2552.      *    WriteIFFData().
  2553.      */
  2554.  
  2555. BOOL
  2556. WriteConfig(STRPTR Name,struct Configuration *LocalConfig)
  2557. {
  2558.     struct IFFHandle *Handle;
  2559.     LONG Error;
  2560.  
  2561.         /* Allocate a handle. */
  2562.  
  2563.     if(Handle = OpenIFFStream(Name,MODE_NEWFILE))
  2564.     {
  2565.             /* Push outmost chunk onto stack. */
  2566.  
  2567.         if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  2568.         {
  2569.             struct TermInfo TermInfo;
  2570.  
  2571.                 /* Add a version identifier. */
  2572.  
  2573.             TermInfo.Version    = CONFIG_FILE_VERSION;
  2574.             TermInfo.Revision    = CONFIG_FILE_REVISION;
  2575.  
  2576.             Error = AddIFFChunkBytes(Handle,ID_VERS,&TermInfo,sizeof(struct TermInfo));
  2577.  
  2578.             if(!Error)
  2579.             {
  2580.                 if(!WriteConfigChunks(Handle,LocalConfig,NULL,NULL))
  2581.                     Error = IoErr();
  2582.             }
  2583.  
  2584.             if(!Error)
  2585.             {
  2586.                 LONG i;
  2587.  
  2588.                 for(i = 0 ; !Error && WindowInfoTable[i].ID != -1 ; i++)
  2589.                 {
  2590.                     Error = AddIFFChunkBytes(Handle,ID_WINF,&WindowInfoTable[i],sizeof(struct WindowInfo));
  2591.                 }
  2592.             }
  2593.  
  2594.                 /* Seems that we're finished, now try to pop the FORM chunk
  2595.                  * and return.
  2596.                  */
  2597.  
  2598.             if(!Error)
  2599.                 Error = PopChunk(Handle);
  2600.  
  2601.             if(Error == OK)
  2602.             {
  2603.                     /* Update the other configuration pointer as well. */
  2604.  
  2605.                 LocalConfig->SerialConfig->LastVersionSaved        = TermVersion;
  2606.                 LocalConfig->SerialConfig->LastRevisionSaved    = TermRevision;
  2607.             }
  2608.         }
  2609.  
  2610.             /* Close the handle (flush any pending data). */
  2611.  
  2612.         CloseIFFStream(Handle);
  2613.     }
  2614.     else
  2615.         Error = IoErr();
  2616.  
  2617.     if(Error)
  2618.     {
  2619.         DeleteFile(Name);
  2620.         SetIoErr(Error);
  2621.  
  2622.         return(FALSE);
  2623.     }
  2624.     else
  2625.     {
  2626.         AddProtection(Name,FIBF_EXECUTE);
  2627.  
  2628.         return(TRUE);
  2629.     }
  2630. }
  2631.  
  2632.     /* ReadConfig(STRPTR Name,struct Configuration *LocalConfig):
  2633.      *
  2634.      *    Read the configuration file, very much the same as ReadIFFData().
  2635.      */
  2636.  
  2637. BOOL
  2638. ReadConfig(STRPTR Name,struct Configuration *LocalConfig)
  2639. {
  2640.     struct IFFHandle *Handle;
  2641.     LONG Error;
  2642.  
  2643.     if(Handle = OpenIFFStream(Name,MODE_OLDFILE))
  2644.     {
  2645.         if(!(Error = StopChunks(Handle,Stops,NUM_STOPS)))
  2646.         {
  2647.             struct WindowInfo WindowInfo;
  2648.             struct ContextNode *Chunk;
  2649.             struct TermInfo TermInfo;
  2650.             LONG ConfigChunkType;
  2651.             LONG Type;
  2652.  
  2653.             memset(&TermInfo,0,sizeof(TermInfo));
  2654.  
  2655.             while(!ParseIFF(Handle,IFFPARSE_SCAN))
  2656.             {
  2657.                 Chunk = CurrentChunk(Handle);
  2658.  
  2659.                 switch(Chunk->cn_ID)
  2660.                 {
  2661.                         /* Oops! Someone is trying to
  2662.                          * use the phone book file as
  2663.                          * a configuration file.
  2664.                          */
  2665.  
  2666.                     case ID_CAT:
  2667.  
  2668.                         Error = ERROR_OBJECT_WRONG_TYPE;
  2669.  
  2670.                         break;
  2671.  
  2672.                         /* File version information. */
  2673.  
  2674.                     case ID_VERS:
  2675.  
  2676.                         if(!ReadIFFBytes(Handle,&TermInfo,sizeof(struct TermInfo)))
  2677.                             Error = IoErr();
  2678.                         else
  2679.                         {
  2680.                             if(TermInfo.Version != CONFIG_FILE_VERSION || (TermInfo.Version == CONFIG_FILE_VERSION && TermInfo.Revision > CONFIG_FILE_REVISION))
  2681.                             {
  2682.                                     /* Old file format (v2.4); stop here and pass
  2683.                                      * control to the compatibility code.
  2684.                                      */
  2685.  
  2686.                                 if(TermInfo.Version == 2 && TermInfo.Revision == 4)
  2687.                                 {
  2688.                                     CloseIFFStream(Handle);
  2689.  
  2690.                                     return(ReadOldConfig(Name,LocalConfig));
  2691.                                 }
  2692.                                 else
  2693.                                 {
  2694.                                     if(TermInfo.Version != 3)
  2695.                                         Error = ERROR_OBJECT_WRONG_TYPE;
  2696.                                 }
  2697.                             }
  2698.                         }
  2699.  
  2700.                         break;
  2701.  
  2702.                         /* Window placement information. */
  2703.  
  2704.                     case ID_WINF:
  2705.  
  2706.                         if(!ReadIFFBytes(Handle,&WindowInfo,sizeof(struct WindowInfo)))
  2707.                             Error = IoErr();
  2708.                         else
  2709.                             ReplaceWindowInfo(&WindowInfo);
  2710.  
  2711.                         break;
  2712.  
  2713.                         /* Special treatment for obsolete "FILE" chunk */
  2714.  
  2715.                     case ID_FILE:
  2716.  
  2717.                         for(Type = PREF_TRANSLATIONFILENAME ; !Error && Type < PREF_RATES ; Type++)
  2718.                         {
  2719.                             if(!CreateConfigEntry(LocalConfig,Type))
  2720.                                 Error = ERROR_NO_FREE_STORE;
  2721.                         }
  2722.  
  2723.                         if(!Error)
  2724.                         {
  2725.                             strcpy(LocalConfig->TranslationFileName,    LocalConfig->FileConfig->TranslationFileName);
  2726.                             strcpy(LocalConfig->MacroFileName,            LocalConfig->FileConfig->MacroFileName);
  2727.                             strcpy(LocalConfig->CursorFileName,            LocalConfig->FileConfig->CursorFileName);
  2728.                             strcpy(LocalConfig->FastMacroFileName,        LocalConfig->FileConfig->FastMacroFileName);
  2729.  
  2730.                             DeleteConfigEntry(LocalConfig,PREF_FILE);
  2731.                         }
  2732.  
  2733.                         break;
  2734.  
  2735.                         /* Any other configuration file chunk. */
  2736.  
  2737.                     default:
  2738.  
  2739.                         if(ConfigChunkType = IsConfigChunk(Chunk->cn_ID))
  2740.                         {
  2741.                             if(!ReadConfigChunk(Handle,LocalConfig,ConfigChunkType,Chunk->cn_Size,NULL))
  2742.                                 Error = IoErr();
  2743.                             else
  2744.                                 FixOldConfig(LocalConfig,ConfigChunkType,FALSE,TermInfo.Version,TermInfo.Revision);
  2745.                         }
  2746.  
  2747.                         break;
  2748.                 }
  2749.  
  2750.                     /* Stop in case of error. */
  2751.  
  2752.                 if(Error)
  2753.                     break;
  2754.             }
  2755.  
  2756.                 /* Patch up configuration file information if necessary. */
  2757.  
  2758.             if(!Error)
  2759.                 FinalFix(LocalConfig,FALSE,TermInfo.Version,TermInfo.Revision);
  2760.         }
  2761.  
  2762.         CloseIFFStream(Handle);
  2763.     }
  2764.     else
  2765.         Error = IoErr();
  2766.  
  2767.     if(Error)
  2768.     {
  2769.         SetIoErr(Error);
  2770.  
  2771.         return(FALSE);
  2772.     }
  2773.     else
  2774.         return(TRUE);
  2775. }
  2776.  
  2777. /*****************************************************************************/
  2778.  
  2779.     /* ResetHotkeys(struct Hotkeys *Hotkeys):
  2780.      *
  2781.      *    Reset hotkey assignments to defaults.
  2782.      */
  2783.  
  2784. VOID
  2785. ResetHotkeys(struct Hotkeys *Hotkeys)
  2786. {
  2787.     strcpy(Hotkeys->termScreenToFront,        "lshift rshift return");
  2788.     strcpy(Hotkeys->BufferScreenToFront,    "control rshift return");
  2789.     strcpy(Hotkeys->SkipDialEntry,            "control lshift rshift return");
  2790.     strcpy(Hotkeys->AbortARexx,                "lshift rshift escape");
  2791.  
  2792.     Hotkeys->CommodityPriority    = 0;
  2793.     Hotkeys->HotkeysEnabled        = TRUE;
  2794. }
  2795.  
  2796.     /* ResetSpeechConfig(struct SpeechConfig *SpeechConfig):
  2797.      *
  2798.      *    Reset speech configuration to defaults.
  2799.      */
  2800.  
  2801. VOID
  2802. ResetSpeechConfig(struct SpeechConfig *SpeechConfig)
  2803. {
  2804.     SpeechConfig->Rate        = DEFRATE;
  2805.     SpeechConfig->Pitch        = DEFPITCH;
  2806.     SpeechConfig->Frequency    = DEFFREQ;
  2807.     SpeechConfig->Volume    = DEFVOL;
  2808.     SpeechConfig->Sex        = DEFSEX;
  2809.     SpeechConfig->Enabled    = FALSE;
  2810. }
  2811.  
  2812.     /* ResetCursorKeys(struct CursorKeys *Keys):
  2813.      *
  2814.      *    Reset cursor key assignments to defaults.
  2815.      */
  2816.  
  2817. VOID
  2818. ResetCursorKeys(struct CursorKeys *Keys)
  2819. {
  2820.     STATIC STRPTR Defaults[4] =
  2821.     {
  2822.         "\\e[A",
  2823.         "\\e[B",
  2824.         "\\e[C",
  2825.         "\\e[D"
  2826.     };
  2827.  
  2828.     LONG i,j;
  2829.  
  2830.     for(i = 0 ; i < 4 ; i++)
  2831.     {
  2832.         for(j = 0 ; j < 4 ; j++)
  2833.             strcpy(Keys->Keys[j][i],Defaults[i]);
  2834.     }
  2835. }
  2836.  
  2837.     /* ResetSound(struct SoundConfig *SoundConfig):
  2838.      *
  2839.      *    Reset the sound settings to defaults.
  2840.      */
  2841.  
  2842. VOID
  2843. ResetSound(struct SoundConfig *SoundConfig)
  2844. {
  2845.     memset(SoundConfig,0,sizeof(struct SoundConfig));
  2846.  
  2847.     SoundConfig->Volume = 100;
  2848.  
  2849.     strcpy(SoundConfig->BellFile,Config->TerminalConfig->BeepFileName);
  2850. }
  2851.  
  2852.     /* ResetMacroKeys(struct MacroKeys *Keys):
  2853.      *
  2854.      *    Reset the macro key assignments to defaults.
  2855.      */
  2856.  
  2857. VOID
  2858. ResetMacroKeys(struct MacroKeys *Keys)
  2859. {
  2860.     STATIC STRPTR FunctionKeyCodes[4] =
  2861.     {
  2862.         "\\eOP",
  2863.         "\\eOQ",
  2864.         "\\eOR",
  2865.         "\\eOS"
  2866.     };
  2867.  
  2868.     LONG i;
  2869.  
  2870.     memset(Keys,0,sizeof(struct MacroKeys));
  2871.  
  2872.     for(i = 0 ; i < 4 ; i++)
  2873.         strcpy(Keys->Keys[1][i],FunctionKeyCodes[i]);
  2874. }
  2875.  
  2876.     /* LoadMacros(STRPTR Name,struct MacroKeys *Keys):
  2877.      *
  2878.      *    Load the keyboard macros from a file.
  2879.      */
  2880.  
  2881. BOOL
  2882. LoadMacros(STRPTR Name,struct MacroKeys *Keys)
  2883. {
  2884.     struct StoredProperty *Prop;
  2885.     struct TermInfo *TermInfo;
  2886.     struct IFFHandle *Handle;
  2887.     LONG Error;
  2888.  
  2889.     if(Handle = OpenIFFStream(Name,MODE_OLDFILE))
  2890.     {
  2891.             /* Collect version number ID if
  2892.              * available.
  2893.              */
  2894.  
  2895.         if(!(Error = PropChunks(Handle,(LONG *)VersionProps,1)))
  2896.         {
  2897.                 /* The following line tells iffparse to stop at the
  2898.                  * very beginning of a `Type' chunk contained in a
  2899.                  * `TERM' FORM chunk.
  2900.                  */
  2901.  
  2902.             if(!(Error = StopChunk(Handle,ID_TERM,ID_KEYS)))
  2903.             {
  2904.                     /* Parse the file... */
  2905.  
  2906.                 if(!ParseIFF(Handle,IFFPARSE_SCAN))
  2907.                 {
  2908.                         /* Did we get a version ID? */
  2909.  
  2910.                     if(Prop = FindProp(Handle,ID_TERM,ID_VERS))
  2911.                     {
  2912.                         TermInfo = (struct TermInfo *)Prop->sp_Data;
  2913.  
  2914.                             /* Is it the file format we are able
  2915.                              * to read?
  2916.                              */
  2917.  
  2918.                         if((TermInfo->Version > CONFIG_FILE_VERSION) || (TermInfo->Version == CONFIG_FILE_VERSION && TermInfo->Revision > CONFIG_FILE_REVISION) || (TermInfo->Version == 1 && TermInfo->Revision < 6))
  2919.                         {
  2920.                                 /* Probably an older revision. */
  2921.  
  2922.                             if(TermInfo->Version == 1 && TermInfo->Revision < 6)
  2923.                             {
  2924.                                 memset(Keys,0,sizeof(struct MacroKeys));
  2925.  
  2926.                                 if(!ReadIFFBytes(Handle,Keys,10 * 256))
  2927.                                     Error = IoErr();
  2928.                             }
  2929.                             else
  2930.                                 Error = ERR_OUTDATED;
  2931.                         }
  2932.                         else
  2933.                         {
  2934.                             /* The file read pointer is positioned
  2935.                              * just in front of the first data
  2936.                              * to be read, so let's don't disappoint
  2937.                              * iffparse and read it.
  2938.                              */
  2939.  
  2940.                             if(!ReadIFFBytes(Handle,Keys,sizeof(struct MacroKeys)))
  2941.                                 Error = IoErr();
  2942.                         }
  2943.                     }
  2944.                     else
  2945.                     {
  2946.                             /* File was created by WriteIFFData previous
  2947.                              * to revision 1.4.
  2948.                              */
  2949.  
  2950.                         memset(Keys,0,sizeof(struct MacroKeys));
  2951.  
  2952.                         if(!ReadIFFBytes(Handle,Keys,10 * 256))
  2953.                             Error = IoErr();
  2954.                     }
  2955.                 }
  2956.             }
  2957.         }
  2958.  
  2959.         CloseIFFStream(Handle);
  2960.     }
  2961.     else
  2962.         Error = IoErr();
  2963.  
  2964.     if(!Error)
  2965.         return(TRUE);
  2966.     else
  2967.     {
  2968.         SetIoErr(Error);
  2969.  
  2970.         return(FALSE);
  2971.     }
  2972. }
  2973.  
  2974. /*****************************************************************************/
  2975.  
  2976.     /* WriteIFFData(STRPTR Name,APTR Data,LONG Size,ULONG Type):
  2977.      *
  2978.      *    Write data to an IFF file (via iffparse.library).
  2979.      */
  2980.  
  2981. BOOL
  2982. WriteIFFData(STRPTR Name,APTR Data,LONG Size,ULONG Type)
  2983. {
  2984.     struct IFFHandle *Handle;
  2985.     LONG Error;
  2986.  
  2987.         /* Allocate a handle. */
  2988.  
  2989.     if(!(Handle = OpenIFFStream(Name,MODE_NEWFILE)))
  2990.         Error = IoErr();
  2991.     else
  2992.     {
  2993.             /* Push outmost chunk onto stack. */
  2994.  
  2995.         if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  2996.         {
  2997.             struct TermInfo TermInfo;
  2998.  
  2999.                 /* Add a version identifier. */
  3000.  
  3001.             TermInfo.Version    = CONFIG_FILE_VERSION;
  3002.             TermInfo.Revision    = CONFIG_FILE_REVISION;
  3003.  
  3004.             Error = AddIFFChunkBytes(Handle,ID_VERS,&TermInfo,sizeof(struct TermInfo));
  3005.  
  3006.                 /* Push the real data chunk on the stack. */
  3007.  
  3008.             if(!Error)
  3009.             {
  3010.                 Error = AddIFFChunkBytes(Handle,Type,Data,Size);
  3011.             }
  3012.  
  3013.                 /* Seems that we're done, now try to pop the FORM chunk
  3014.                  * and return.
  3015.                  */
  3016.  
  3017.             if(!Error)
  3018.                 Error = PopChunk(Handle);
  3019.         }
  3020.  
  3021.         CloseIFFStream(Handle);
  3022.     }
  3023.  
  3024.     if(!Error)
  3025.     {
  3026.         AddProtection(Name,FIBF_EXECUTE);
  3027.  
  3028.         return(TRUE);
  3029.     }
  3030.     else
  3031.     {
  3032.         DeleteFile(Name);
  3033.         SetIoErr(Error);
  3034.  
  3035.         return(FALSE);
  3036.     }
  3037. }
  3038.  
  3039.     /* ReadIFFData(STRPTR Name,APTR Data,LONG Size,ULONG Type):
  3040.      *
  3041.      *    Read data from a `TERM' FORM chunk contained in an IFF file.
  3042.      */
  3043.  
  3044. BOOL
  3045. ReadIFFData(STRPTR Name,APTR Data,LONG Size,ULONG Type)
  3046. {
  3047.     struct IFFHandle *Handle;
  3048.     LONG Error;
  3049.  
  3050.     if(!(Handle = OpenIFFStream(Name,MODE_OLDFILE)))
  3051.         Error = IoErr();
  3052.     else
  3053.     {
  3054.             /* Collect version number ID if
  3055.              * available.
  3056.              */
  3057.  
  3058.         if(!(Error = PropChunks(Handle,(LONG *)VersionProps,1)))
  3059.         {
  3060.                 /* The following line tells iffparse to stop at the
  3061.                  * very beginning of a `Type' chunk contained in a
  3062.                  * `TERM' FORM chunk.
  3063.                  */
  3064.  
  3065.             if(!(Error = StopChunk(Handle,ID_TERM,Type)))
  3066.             {
  3067.                     /* Parse the file... */
  3068.  
  3069.                 if(!ParseIFF(Handle,IFFPARSE_SCAN))
  3070.                 {
  3071.                     struct StoredProperty *Prop;
  3072.  
  3073.                         /* Did we get a version ID? */
  3074.  
  3075.                     if(!(Prop = FindProp(Handle,ID_TERM,ID_VERS)))
  3076.                         Error = ERR_OUTDATED;
  3077.                     else
  3078.                     {
  3079.                         struct TermInfo *TermInfo;
  3080.  
  3081.                         TermInfo = (struct TermInfo *)Prop->sp_Data;
  3082.  
  3083.                             /* Is it the file format we are able
  3084.                              * to read?
  3085.                              */
  3086.  
  3087.                         if((TermInfo->Version > CONFIG_FILE_VERSION) || (TermInfo->Version == CONFIG_FILE_VERSION && TermInfo->Revision > CONFIG_FILE_REVISION) || (TermInfo->Version == 1 && TermInfo->Revision < 6))
  3088.                             Error = ERR_OUTDATED;
  3089.                         else
  3090.                         {
  3091.                             struct ContextNode *Chunk = CurrentChunk(Handle);
  3092.  
  3093.                             if(Chunk->cn_Size < Size)
  3094.                                 Size = Chunk->cn_Size;
  3095.  
  3096.                                 /* The file read pointer is positioned
  3097.                                  * just in front of the first data
  3098.                                  * to be read, so let's don't disappoint
  3099.                                  * iffparse and read it.
  3100.                                  */
  3101.  
  3102.                             if(!ReadIFFBytes(Handle,Data,Size))
  3103.                                 Error = IoErr();
  3104.                         }
  3105.                     }
  3106.                 }
  3107.             }
  3108.         }
  3109.  
  3110.         CloseIFFStream(Handle);
  3111.     }
  3112.  
  3113.     if(!Error)
  3114.         return(TRUE);
  3115.     else
  3116.     {
  3117.         SetIoErr(Error);
  3118.         return(FALSE);
  3119.     }
  3120. }
  3121.